Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/asp.net/35.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Asp.net 为动态生成的孙子控件向UpdatePanel添加PostBackTriggers和AsyncPostBackTriggers_Asp.net_Asp.net Ajax_Updatepanel_Asp.net 3.5 - Fatal编程技术网

Asp.net 为动态生成的孙子控件向UpdatePanel添加PostBackTriggers和AsyncPostBackTriggers

Asp.net 为动态生成的孙子控件向UpdatePanel添加PostBackTriggers和AsyncPostBackTriggers,asp.net,asp.net-ajax,updatepanel,asp.net-3.5,Asp.net,Asp.net Ajax,Updatepanel,Asp.net 3.5,我有一个带有ScriptManager的页面、一个通用HTML下拉列表()和一个UpdatePanel。UpdatePanel包含一个占位符(目前)。在页面加载期间,许多用户控件被添加到占位符中(实际上,它是同一用户控件的多个实例)。要添加的数字在页面加载之前是未知的,因此需要动态加载。下拉列表中填充了相同数量的菜单项,页面上也有javascript(使用jQuery),根据下拉列表的状态一次只显示一个控件 每个用户控件都有两个按钮,用于生成异步回发;一个下拉列表,用于在选定值发生更改时生成异步

我有一个带有ScriptManager的页面、一个通用HTML下拉列表(
)和一个UpdatePanel。UpdatePanel包含一个占位符(目前)。在页面加载期间,许多用户控件被添加到占位符中(实际上,它是同一用户控件的多个实例)。要添加的数字在页面加载之前是未知的,因此需要动态加载。下拉列表中填充了相同数量的菜单项,页面上也有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>
因此,我想知道是否需要在客户端注册触发器,而不是使用ASP.NET Ajax。我发现这基本上可以解释为什么。但是,我不知道如何考虑EventName。到目前为止,我看到的示例只是添加按钮点击,但我不知道如何处理DropDownList中SelectedIndexChanged事件

有人帮忙吗?有没有我错过的例子?当然,我给出的链接中的方法似乎是“非官方的”,所以我没有看到任何关于这个主题的MSDN文档


谢谢

我的建议是将所有控件(包括此UpdatePanel)从此UpdatePanel中拉入UserControl。在usercontrol中定义在单击按钮或更改下拉列表的选定索引时引发的事件。在保存占位符的页面中处理这些事件(在单个UpdatePanel中,有条件,无触发器)。如果添加UserControls,请手动调用主更新面板的更新方法

为了澄清我的意思,请看以下示例:

主页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
<%@ 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>
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
ascx,用于保存控件:

<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
<%@ 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>
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强制转换为用户控件的类型:
    Dim uc As DynamicControls=DirectCast(DirectCast(发件人,控件).NamingContainer,DynamicControls)
  • 将所有出现的
    (ByVal sender作为对象,ByVal e作为System.EventArgs)
    替换为
    (uc作为动态控件)
    。通过这种方式,UserControl的引用将作为参数添加到事件中,您可以从页面访问它的公共属性,例如:

    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中。记住要正确地设置参数。例如:

    <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> 
    
    
    请稍候。。。
    请稍候。。。
    内容
    
    您正在使用.net framework 4.0吗?我这样问是因为现在你对control有了更多的控制权。ClientID:@Tim No,现在必须是.NET 3.5。标记为3.5。我稍后会进去仔细看看,谢谢。我已经调试了这个应用程序,我认为这或多或少是可行的。你知道在这种情况下,当其中一个触发器被触发时,如何让UpdateProgress显示出来吗?我已经尝试过将UpdateProgress放在页面和控件中(在这两种情况下都在实际的UpdatePanel之外),但在这两种情况下都没有出现。@Andrew;我已经用一个对我有用的样本更新了我的答案(为了简化而没有任何内容)。它在UserControl中有两个UpdatePanel。根据您的要求进行调整。