Ajax启用.NET Server Control已注册

时间:2009-09-09 14:38:48

标签: .net asp.net asp.net-ajax

我已经创建了一个支持Ajax的.NET Server控件。此控件继承Panel并实现IScriptControl(以便启用控件的Ajax组件)。

实际上这很简单。它本质上是一个具有溢出样式的面板:滚动(它是一个“可滚动面板”),它记住它在服务器的异步回发之间的滚动位置,这样滚动位置不会重置为0,异步回发返回时为0。

现在一切都已经工作了一段时间(几年),但我从未试图让这个控件不可见(服务器端)。即使我将此控件的父级设置为Visible = false,此控件也无法正常工作。

我在Web浏览器中遇到了Ajax.NET框架引发的异常:

错误:Sys.ScriptLoadFailedException:脚本“http://UrlToAScript”包含对Sys.Application.notifyScriptLoaded()的多次调用。只允许一个。

它与Render事件没有被触发有关(因为控件不可见,它没有渲染,所以Render事件实际上没有发生)。当控件可见时(并且Render事件确实发生)我在Web浏览器(客户端)中看到异常,表明它已经多次注册。 (希望我正在向听众讲话,他们了解ScriptDescriptors是在启用Ajax的服务器控件的Render事件中使用ScriptManager注册的。)

这是我处理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 个答案:

答案 0 :(得分:2)

我找到了问题的答案。

我在我的JavaScript代码中使用了以下启用了Ajax的服务器控件:

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

由于某些原因,如果控件的可见性状态在服务器上发生更改,则此行也会(自动)由.NET添加。奇怪的是,.NET只在控件的可见性状态发生变化时才添加,而不是每次都添加。

我删除了我的“if(typeof(Sys)!=='undefined')Sys.Application.notifyScriptLoaded();”然后让.NET为我添加这一行,一切正常现在

编辑:显然,当您使用ControlJS模板时,此行会自动添加到Control的JavaScript中。因此,如果您正在创建控件,请注意此问题。请确保删除此行,否则您可能会遇到与我相同的问题。

谢谢你的时间!

-Frinny