I've created an Ajax enabled .NET Server control. This control inherits a Panel and implements the IScriptControl (in order to enable the Ajax component of the control).
It's pretty simple actually. It's essentially a Panel that has a style of overflow:scroll (it's a "scrollable Panel") and it remembers it's scroll position between asynchronous postbacks to the server so that the scroll position is not reset to 0,0 when the asynchronous postback returns.
Everything's been working for some time now (years) but I never tried to make this control invisible (server side). Even if I set the parent of this control to Visible=false this control is not working properly.
I'm getting an exception thrown by the Ajax.NET framework in the web browser:
Error: Sys.ScriptLoadFailedException: The script "http://UrlToAScript" contains multiple calls to Sys.Application.notifyScriptLoaded(). Only one is allowed.
It has something to do with the Render event not being fired (because the control is not visible, it's not rendered so the Render event doesn't actually take place). When the control is made visible (and the Render event does take place) I'm seeing the exception in the web browser (client side) stating that it's registered more than once. (Hopefully I'm speaking to an audience that understands that the ScriptDescriptors are registered with the ScriptManager in the Render event of Ajax enabled server controls.)
Here is my implementation that handles the OnPreRender and Render events:
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
I have no idea how to get around this problem. Any insight would be greatly appreciated.
Thanks a lot,
-Frinny