asp.net – 为动态生成的孙子控件添加PostBackTriggers和AsyncPostBackTriggers到UpdatePanel

前端之家收集整理的这篇文章主要介绍了asp.net – 为动态生成的孙子控件添加PostBackTriggers和AsyncPostBackTriggers到UpdatePanel前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。
我有一个带有ScriptManager的页面,一个通用的HTML下拉列表(< select>)和一个UpdatePanel. UpdatePanel包含一个PlaceHolder(暂时).在Page_Load期间,PlaceHolder中添加了许多用户控件(实际上,它是同一用户控件的几个实例).在页面加载之前,要添加的数字是未知的,因此需要动态加载它们.下拉列表中填充了相同数量菜单项,并且页面上还有javascript(使用jQuery),一次只显示一个控件,具体取决于下拉列表的状态.

每个用户控件都有两个应该生成异步回发的按钮,一个应该在所选值的更改中生成异步回发的下拉列表,以及一个应该生成同步回发的按钮.如果我没有动态生成控件,并且如果只有一个控件,结构将类似于:

<asp:UpdatePanel ID="myUpdatePanel" runat="server" UpdateMode="Conditional"
                 ChildrenAsTriggers="false">
    <ContentTemplate>
        <asp:TextBox ID="textBox1" runat="server" />
        <asp:TextBox ID="textBox2" runat="server" />
        <asp:Button ID="asyncButton1" runat="server" Text="Button1"
                    onclick="asyncButton1_Click" />
        <asp:DropDownList ID="asyncDropDown" ruant="server" AutoPostBack="true"
                    OnSelectedIndexChanged="asyncDropDown_SelectedIndexChanged" />
        <asp:Button ID="asyncButton2" runat="server" Text="Button2"
                    OnClick="asyncButton2_Click" />
        <asp:Button ID="syncButton" runat="server" Text="SyncButton"
                    OnClick="syncButton_Click" />
    </ContentTemplate>
    <Triggers>
        <asp:AsyncPostBackTrigger ControlID="asyncButton1" EventName="Click" />
        <asp:AsyncPostBackTrigger ControlID="asyncButton2" EventName="Click" />
        <asp:AsyncPostBackTrigger ControlID="asyncDropDown"
            EventName="SelectedIndexChanged" />
        <asp:PostBackTrigger ControlID="syncButton" />
    </Triggers>
</asp:UpdatePanel>

当然,ContentTemplate中的所有控件实际上都是每个用户控件的一部分.

在服务器端添加触发器似乎不起作用,因为没有ControlID似乎可以帮助UpdatePanel找到相关的控件.我可以使用控件的ID或控件的UniqueID,它不起作用,我得到一个错误的行

A control with ID 'ctl00$ContentPlaceHolder1$ctl01$asyncButton1' could not be
found for the trigger in UpdatePanel 'myUpdatePanel'.

所以,我想知道是否需要在客户端注册触发器而不是使用ASP.NET Ajax.我发现this page基本上解释了如何.但是,我不知道如何考虑EventName.到目前为止我看到的例子只是添加按钮点击,但我不知道如何处理DropDownList中的SelectedIndexChanged事件.

有什么帮助吗?那里有我错过的例子吗?当然,我提供的链接中的方法似乎是“非官方的”,这没有帮助,因此我没有看到关于该主题的任何MSDN文档.

谢谢!

解决方法

我的建议是将包含此UpdatePanel的所有控件从此UpdatePanel中提取到UserControl中.定义在单击按钮或下拉列表的选定索引发生更改时引发的usercontrol中的事件.在包含占位符的页面中处理这些事件(在单个UpdatePanel中,有条件,没有触发器).如果添加UserControls,请手动调用主更新面板的Update-method.

为了澄清我的意思,请看下面的例子:

页面aspx:

<asp:UpdatePanel ID="Upd1" runat="server" UpdateMode="Conditional">
  <ContentTemplate>
     <asp:PlaceHolder ID="PlaceHolder1" runat="server"></asp:PlaceHolder>
  </ContentTemplate>
</asp:UpdatePanel>

代码隐藏:

Private Property UserControlCount() As Int32
        Get
            If ViewState("UserControlCount") Is Nothing Then
                ViewState("UserControlCount") = 1
            End If
            Return DirectCast(ViewState("UserControlCount"),Int32)
        End Get
        Set(ByVal value As Int32)
            ViewState("UserControlCount") = value
        End Set
    End Property

    Protected Sub Page_Load(ByVal sender As Object,ByVal e As System.EventArgs) Handles Me.Load
        recreateUserControls()
    End Sub

    Private Sub recreateUserControls()
        For i As Int32 = 1 To Me.UserControlCount
            Dim uc As DynamicControls = DirectCast(Me.LoadControl("DynamicControls.ascx"),DynamicControls)
            uc.ID = "DynamicControls_" & i
            Addhandlers(uc)
            Me.PlaceHolder1.Controls.Add(uc)
        Next
    End Sub

    Private Sub Addhandlers(ByVal uc As DynamicControls)
        AddHandler uc.asyncButton1Clicked,AddressOf ucAsyncButton1Clicked
        AddHandler uc.asyncButton2Clicked,AddressOf ucAsyncButton2Clicked
        AddHandler uc.syncButtonClicked,AddressOf ucSyncButtonClicked
        AddHandler uc.asyncDropDownSelectedIndexChanged,AddressOf ucAsyncDropDownSelectedIndexChanged
    End Sub

    Private Sub addUserControl()
        Me.UserControlCount += 1

        Dim uc As DynamicControls = DirectCast(Me.LoadControl("DynamicControls.ascx"),DynamicControls)
        uc.ID = "DynamicControls_" & Me.UserControlCount
        Addhandlers(uc)
        Me.PlaceHolder1.Controls.Add(uc)

        Upd1.Update()
    End Sub

    Private Sub ucAsyncButton1Clicked(ByVal sender As Object,ByVal e As EventArgs)
        'only to demonstrate how to add control dynamically and update the UpdatePanel'
        addUserControl()
        Me.Upd1.Update()
    End Sub

    Private Sub ucAsyncButton2Clicked(ByVal sender As Object,ByVal e As EventArgs)
    End Sub

    Private Sub ucSyncButtonClicked(ByVal sender As Object,ByVal e As EventArgs)
    End Sub

    Private Sub ucAsyncDropDownSelectedIndexChanged(ByVal sender As Object,ByVal e As EventArgs)
    End Sub

包含控件的ascx:

<%@ Control Language="vb" AutoEventWireup="false" CodeBehind="DynamicControls.ascx.vb" Inherits="AJAXEnabledWebApplication1.DynamicControls" %>
<%@ Register Assembly="AjaxControlToolkit" Namespace="AjaxControlToolkit" TagPrefix="asp" %>

<asp:UpdatePanel ID="myUpdatePanel" runat="server" UpdateMode="Conditional"
                 ChildrenAsTriggers="false">
    <ContentTemplate>
        <asp:TextBox ID="textBox1" runat="server" />
        <asp:TextBox ID="textBox2" runat="server" />
        <asp:Button ID="asyncButton1" runat="server" Text="Button1" />
        <asp:DropDownList ID="asyncDropDown" runat="server" AutoPostBack="true" />
        <asp:Button ID="asyncButton2" runat="server" Text="Button2" />
        <asp:Button ID="syncButton" runat="server" Text="SyncButton" />
    </ContentTemplate>
    <Triggers>
        <asp:AsyncPostBackTrigger ControlID="asyncButton1" EventName="Click" />
        <asp:AsyncPostBackTrigger ControlID="asyncButton2" EventName="Click" />
        <asp:AsyncPostBackTrigger ControlID="asyncDropDown" EventName="SelectedIndexChanged" />
        <asp:PostBackTrigger ControlID="syncButton" />
    </Triggers>
</asp:UpdatePanel>

UserControl的代码隐藏:

Public Partial Class DynamicControls
    Inherits System.Web.UI.UserControl

    Public Event asyncButton1Clicked(ByVal sender As Object,ByVal e As System.EventArgs)
    Public Event asyncButton2Clicked(ByVal sender As Object,ByVal e As System.EventArgs)
    Public Event syncButtonClicked(ByVal sender As Object,ByVal e As System.EventArgs)
    Public Event asyncDropDownSelectedIndexChanged(ByVal sender As Object,ByVal e As System.EventArgs)

    Private Sub asyncButton1_Click(ByVal sender As Object,ByVal e As System.EventArgs) Handles asyncButton1.Click
        RaiseEvent asyncButton1Clicked(sender,e)
    End Sub

    Private Sub asyncButton2_Click(ByVal sender As Object,ByVal e As System.EventArgs) Handles asyncButton2.Click
        RaiseEvent asyncButton2Clicked(sender,e)
    End Sub

    Private Sub syncButton_Click(ByVal sender As Object,ByVal e As System.EventArgs) Handles syncButton.Click
        RaiseEvent syncButtonClicked(sender,e)
    End Sub

    Private Sub asyncDropDown_SelectedIndexChanged(ByVal sender As Object,ByVal e As System.EventArgs) Handles asyncDropDown.SelectedIndexChanged
        RaiseEvent asyncDropDownSelectedIndexChanged(sender,e)
    End Sub
End Class

通过这种方式,您不会遇到ClientID的问题.

加成:
如果需要在事件处理程序中访问UserControls的控件,请使用以下两个选项之一:

>将发送者的NamingContainer强制转换为userControl的类型:Dim uc As DynamicControls = DirectCast(DirectCast(sender,Control).NamingContainer,DynamicControls)
>使用(uc as DynamicControls)替换(ByVal sender As Object,ByVal e As System.EventArgs)的所有出现.通过这种方式,您的UserControl的引用将作为参数添加到事件中,您可以从页面访问它的公共属性,f.e.:

dim txt1 as String = uc.Text1

如果您在UserControl中公开了属性Text1:

Public Property Text1() As String
     Get
         Return textBox1.Text
     End Get
     Set(ByVal value As String)
         textBox1.Text = value
     End Set
 End Property

第二种选择是最干净,最易读的方式.

更新:
根据您的评论:您应该将UpdateProgress放在更新的UpdatePanel内的UserControl中.请记住正确设置AssociatedUpdatePanelID.例如:

<asp:UpdatePanel ID="UdpForm" runat="server" UpdateMode="conditional" ChildrenAsTriggers="false"  >
  <ContentTemplate>
    <asp:panel ID="FormPanel" runat="server">
        <asp:UpdateProgress ID="UpdateProgress1" DynamicLayout="true" runat="server" AssociatedUpdatePanelID="UdpForm" DisplayAfter="0" >
            <ProgressTemplate>
            <div class="progress">
                <asp:Image ID="ImgProgress1" runat="server" ImageUrl="~/images/ajax-loader-arrows.gif" ToolTip="loading..." />&nbsp;please wait...
            </div>
            </ProgressTemplate>
         </asp:UpdateProgress>     
         <asp:FormView ID="FormView1"  runat="server" DefaultMode="ReadOnly"  >
             <ItemTemplate></ItemTemplate>
             <EditItemTemplate></EditItemTemplate>
             <InsertItemTemplate></InsertItemTemplate>
             <EmptyDataTemplate>
             </EmptyDataTemplate>
             <PagerTemplate >
             </PagerTemplate>
        </asp:FormView>
     </asp:panel>
  </contenttemplate>
</asp:UpdatePanel> 

<asp:UpdatePanel ID="UpdContent" runat="server" UpdateMode="conditional" ChildrenAsTriggers="false"  >
  <ContentTemplate>
     <asp:Panel ID="PnlMain" runat="server">
        <asp:UpdateProgress ID="UpdateProgress2" DynamicLayout="true" runat="server" AssociatedUpdatePanelID="UpdContent" DisplayAfter="0" >
            <ProgressTemplate>
            <div class="progress">
                <asp:Image ID="ImgProgress1" runat="server" ImageUrl="~/images/ajax-loader-arrows.gif" ToolTip="loading..." />&nbsp;please wait...
            </div>
            </ProgressTemplate>
         </asp:UpdateProgress>

         Content

   </asp:Panel>
 </ContentTemplate> 
   <Triggers ></Triggers>
</asp:UpdatePanel>

猜你在找的asp.Net相关文章