gpt4 book ai didi

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

转载 作者:行者123 更新时间:2023-12-04 18:52:01 30 4
gpt4 key购买 nike

我有一个带有 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 中。在您的用户控件中定义在单击按钮或更改下拉菜单的选定索引时引发的事件。在包含占位符的页面中处理这些事件(在单个 UpdatePanel 中,有条件,无触发器)。如果添加用户控件,请手动调用主更新面板的更新方法。

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

主页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)
  • 替换所有出现的 (ByVal sender As Object, ByVal e As System.EventArgs)(uc as DynamicControls) .通过这种方式,您的 UserControl 的引用作为参数添加到事件中,您可以从页面访问它的公共(public)属性,例如:
    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 - 为动态生成的孙控件添加 PostBackTriggers 和 AsyncPostBackTriggers 到 UpdatePanel,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4742208/

    30 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com