I created a .NET Server control with Ajax support. This control inherits the panel and implements IScriptControl (to enable the Ajax component of the control).
It is pretty simple. This is essentially a panel that has an overflow style: scroll (this is a "scrollable panel"), and it remembers its scroll position between asynchronous postbacks to the server, so that the scroll position does not reset to 0.0 when the asynchronous postback returns .
Everything has been working for some time (years), but I never tried to make this control invisible (server side). Even if I set the parent of this Visible = false control, this control does not work correctly.
I get an exception thrown by an Ajax.NET map in a web browser:
Error: Sys.ScriptLoadFailedException: script " http: // UrlToAScript " contains several calls to Sys.Application.notifyScriptLoaded (). Only one is allowed.
This is because the Render event is not triggered (since the control is not displayed, it is not displayed, so the Render event is not actually executed). When the control becomes visible (and the Render event occurs), I see an exception in the web browser (client side), stating that it is registered more than once. (Hopefully, I’ll talk to an audience that understands that ScriptDescriptors are registered with ScriptManager in the Render event for Ajax servers.)
Here is my implementation that handles 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 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