添加PostBackTriggers和AsyncPostBackTriggers到UpdatePanel中动态生成的孙子控制 [英] Adding PostBackTriggers and AsyncPostBackTriggers to UpdatePanel for dynamically-generated grandchild controls

查看:114
本文介绍了添加PostBackTriggers和AsyncPostBackTriggers到UpdatePanel中动态生成的孙子控制的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个网页一个ScriptManager,一个通用的HTML下拉列表(<选择> )和一个UpdatePanel。在UpdatePanel中包含的占位符(现在)。在Page_Load期间,一些用户控件添加到占位符(实际上,这是相同的用户控件的多个实例)。要添加的号码是不知道,直到页面加载,这样他们就需要进行动态加载。在下拉列表中填充了相同数目的菜单项,并有JavaScript的网页上也(使用jQuery)显示一次只取决于下拉列表中的状态控件之一。

I have a page with a ScriptManager, a generic HTML drop-down list (<select>), and an UpdatePanel. The UpdatePanel contains a PlaceHolder (for now). During Page_Load, a number of user controls are added to the PlaceHolder (really, it's several instances of the same user control). The number to add is not known until the page loads, so they do need to be loaded dynamically. The drop-down list is populated with the same number of menu items, and there is javascript on the page also (using jQuery) to show only one of the controls at a time depending on the state of the drop-down list.

每个用户控件有两个按钮,应该产生一个异步回发,一个下拉列表应该产生在选定值的变化异步回发,这应该产生一个同步回发的按钮。如果我没有产生动态的控制,如果只有一个控制,结构会是这样的:

Each user control has two buttons that should generate an asynchronous postback, a drop-down list that should generate an asynchronous postback on a change in selected value, and a button that should generate a synchronous postback. If I was not generating the controls dynamically, and if there was only one control, the structure would be something like:

<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内的控制实际上是每个用户控制的一部分。

Of course, all the controls inside the ContentTemplate would actually be part of each user control.

添加服务器端的触发器似乎并没有工作,因为没有控件ID似乎帮助在UpdatePanel找到相关的控制。我可以使用该控件的ID或控件的UniqueID的,它不工作,我相处的。

Adding the triggers on the server side does not seem to work because no ControlID seems to help the UpdatePanel find the relevant controls. I can use either the control's ID or the control's UniqueID, and it does not work, and I get an error along the lines of

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

所以,我不知道是否需要注册,而不是使用ASP.NET AJAX客户端的触发器。我发现此页面基本上解释了如何。但是,我不知道怎么去考虑到事件名称。到目前为止,我所看到的例子而仅仅在加入按钮点击,但我不知道如何处理从DropDownList的SelectedIndexChanged事件。

So, I wonder if I need to register the triggers in the client instead using ASP.NET Ajax. I found this page that basically explains how. However, I do not know how to get the EventName taken into consideration. The examples I have seen so far have merely been adding button clicks, but I don't know how to handle the SelectedIndexChanged event from the DropDownList.

任何帮助吗?是否有例子在那里我错过了什么?它没有帮助,当然,在我给的链接方法似乎是非官方的,所以我没有看到关于这个问题的任何文件MSDN

Any help here? Are there examples out there I have missed? It doesn't help, of course, that the method in the link I gave appears to be "unofficial," so I don't see any MSDN documents on the subject.

谢谢!

推荐答案

我的建议是拉所有控件包容这个UpdatePanel中出这个UpdatePanel中的成用户控件。定义你的用户控件的事件被点击或下拉的选择指数得到改变的按钮时所引发。处理您的网页,这些事件保持占位符(在一个单一的UpdatePanel,有条件的,没有触发器)。手动调用主更新面板的更新,方法,如果您添加用户控件。

My suggestion would be to pull all your controls inclusive this UpdatePanel out of this UpdatePanel into an UserControl. Define events in your usercontrol that are raised when the buttons are clicked or the Dropdown's selected index get changed. Handle these events in your page that holds the Placeholder(in a single UpdatePanel,conditional,without triggers). Call the Update-method of the main update panel manually if you add UserControls.

要澄清我的意思是看看下面的例子:

To clarify what i mean have a look at following example:

主要页面的aspx:

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

codebehind:

  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>

用户控件的 codebehind:

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

在这种方式,你不会有客户端ID的问题。

On this way you won't have problems with ClientID's.

增加:
如果您需要访问在事件处理程序的用户控件的控件,使用以下两种方法之一:

Addition: If you need access to the controls of your UserControls in the event-handlers, use one of following two options:


  1. 投发件人的NamingContainer到用户控件的类型:昏暗UC作为DynamicControls = DirectCast(DirectCast(发件人,控制).NamingContainer,DynamicControls)

  2. 替换(BYVAL发件人为对象,BYVAL E上System.EventArgs)出现的所有(UC作为DynamicControls)。在这条路上你的用户控件的引用添加到事件作为参数,你可以从网页,f.e访问它的公共属性。

  1. cast the sender's NamingContainer to the userControl's type: Dim uc As DynamicControls = DirectCast(DirectCast(sender, Control).NamingContainer, DynamicControls)
  2. replace all occurences of (ByVal sender As Object, ByVal e As System.EventArgs) with (uc as DynamicControls). On this way the reference of your UserControl is added to the event as parameter and you could access public properties of it from the page, f.e.:

dim txt1 as String = uc.Text1


如果您已暴露的属性文本1中的用户控件:

If you have exposed a property Text1 in the UserControl:

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

第二个选项是最干净,最可读的方式。

The second option is the cleanest and most readable way.

更新
根据您的评论:你应该把在该用户的的UpdateProgress即得到更新在UpdatePanel内。请记住,设置<一个href=\"http://msdn.microsoft.com/en-us/library/system.web.ui.updateprogress.associatedupdatepanelid.aspx\"相对=nofollow> 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> 

这篇关于添加PostBackTriggers和AsyncPostBackTriggers到UpdatePanel中动态生成的孙子控制的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆