Ajax включен. NET Server Control зарегистрирован - PullRequest
3 голосов
/ 09 сентября 2009

Я создал элемент управления .NET Server с поддержкой Ajax. Этот элемент управления наследует Panel и реализует IScriptControl (для включения компонента Ajax элемента управления).

Это довольно просто на самом деле. По сути, это панель, которая имеет стиль переполнения: scroll (это «прокручиваемая панель») и запоминает позицию прокрутки между асинхронными обратными передачами на сервер, поэтому позиция прокрутки не сбрасывается на 0,0 когда асинхронная обратная передача возвращается.

Все работает уже некоторое время (годы), но я никогда не пытался сделать этот элемент управления невидимым (на стороне сервера). Даже если для родителя этого элемента управления установлено значение Visible = false, этот элемент управления работает неправильно.

Я получаю исключение, выданное платформой Ajax.NET в веб-браузере:

Ошибка: Sys.ScriptLoadFailedException: сценарий "http://UrlToAScript" содержит несколько вызовов Sys.Application.notifyScriptLoaded (). Допускается только один.

Это связано с тем, что событие Render не было запущено (поскольку элемент управления не отображается, он не отображается, поэтому событие Render на самом деле не происходит). Когда элемент управления становится видимым (и событие Render имеет место), я вижу исключение в веб-браузере (на стороне клиента), заявляющее, что оно зарегистрировано более одного раза. (Надеюсь, я обращаюсь к аудитории, которая понимает, что ScriptDescriptors зарегистрированы в ScriptManager в событии Render серверных элементов управления с поддержкой Ajax.)

Вот моя реализация, которая обрабатывает события OnPreRender и Render:

Protected Overrides Sub OnPreRender(ByVal e As System.EventArgs)
        Me.Style.Add("overflow", "scroll")

        If Not Me.DesignMode Then
            If ScriptManager Is Nothing Then
                Throw New HttpException("A ScriptManager control must exist on the page.")
            End If
            ScriptManager.RegisterScriptControl(Me)
        End If
        MyBase.OnPreRender(e)
    End Sub
    Protected Overrides Sub Render(ByVal writer As System.Web.UI.HtmlTextWriter)
        'Register the ScrollContiner's script descriptors that are created by the GetScriptDescriptors method
        If Not Me.DesignMode Then
            ScriptManager.RegisterScriptDescriptors(Me)
        End If
        MyBase.Render(writer)
    End Sub
    Public Function GetScriptReferences() As System.Collections.Generic.IEnumerable(Of System.Web.UI.ScriptReference) Implements System.Web.UI.IScriptControl.GetScriptReferences

        Dim reference As ScriptReference = New ScriptReference()
        reference.Name = "MyNamespace.ScrollContainer.js"
        reference.Assembly = "MyNamespace"

        Return New ScriptReference() {reference}
    End Function 
    Public Function GetScriptDescriptors() As System.Collections.Generic.IEnumerable(Of System.Web.UI.ScriptDescriptor) Implements System.Web.UI.IScriptControl.GetScriptDescriptors
        Dim descriptor As ScriptControlDescriptor = New ScriptControlDescriptor("MyNamespace.ScrollContainer", Me.ClientID)
        descriptor.AddProperty("LeftScrollPosition", Me.LeftScrollPosition)
        descriptor.AddProperty("RightScrollPosition", Me.RightScrollPosition)
        descriptor.AddProperty("ScrollPositionMessengerName", Me.ScrollPositionMessengerName)
        Return New ScriptDescriptor() {descriptor}
    End Function

Понятия не имею, как обойти эту проблему. Любая идея будет принята с благодарностью.

Большое спасибо,

-Frinny

1 Ответ

2 голосов
/ 10 сентября 2009

Я нашел ответ на мою проблему.

В моем коде JavaScript было следующее, что использовал мой серверный элемент управления с поддержкой Ajax:

if (typeof (Sys) !== 'undefined')  Sys.Application.notifyScriptLoaded();

По какой-то причине эта строка также (автоматически) добавляется .NET, если состояние видимости элемента управления изменяется на сервере. Странно то, что .NET добавлял его только тогда, когда состояние видимости элемента управления менялось, а не каждый раз.

Я удалил свой "if (typeof (Sys)! == 'undefined') Sys.Application.notifyScriptLoaded ();" и просто позволил .NET добавить эту строку для меня, и теперь все работает нормально .

Редактировать : очевидно, эта строка автоматически добавляется в JavaScript элемента управления при использовании шаблона ControlJS. Итак, остерегайтесь этой проблемы, если вы создаете элементы управления. Убедитесь, что вы удалили эту строку, иначе у вас возникнет та же проблема, что и у меня.

Спасибо за ваше время!

-Frinny

...