Asp.net 动态创建的用户控件无法处理回发事件
我有一个用户控件,它在页面的Init中使用以下代码动态加载到页面中Asp.net 动态创建的用户控件无法处理回发事件,asp.net,dynamic,user-controls,postback,Asp.net,Dynamic,User Controls,Postback,我有一个用户控件,它在页面的Init中使用以下代码动态加载到页面中 Dim oCtl As Object oCtl = LoadControl("~/Controls/UserControl1.ascx") oCtl.Id = "UserControl11" PlaceHolder1.Controls.Clear() PlaceHolder1.Controls.Add(oCtl) 用户控件还包含一个按钮,我无法捕获用户控件中的按钮单击 几个问题: 在页面生命周期的什么时候加载控件 事件处理程
Dim oCtl As Object
oCtl = LoadControl("~/Controls/UserControl1.ascx")
oCtl.Id = "UserControl11"
PlaceHolder1.Controls.Clear()
PlaceHolder1.Controls.Add(oCtl)
用户控件还包含一个按钮,我无法捕获用户控件中的按钮单击 几个问题:
最后,.Net的风格指南特别建议不要使用任何hugarian前缀,比如oCtl中的o,并且您应该将其作为控件而不是对象键入。您只想在不回发时加载控件请确保在每次回发时加载控件-如果在回发页面时控件不在控件树中,ASP.NET将不会引发按钮单击事件 在.NET进入页面生命周期的“回发事件处理”步骤之前,必须确保该控件存在于页面上。由于控件是动态添加的,因此您必须确保在每次回发时都重新创建该控件,以便它可以找到触发事件的控件。以下是页面的完整代码
Partial Class DynamicLoad
Inherits System.Web.UI.Page
Protected Sub Page_Init(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Init
If IsPostBack Then
If Not (Session("ctl") Is Nothing) Then
Dim oCtl As Object
oCtl = Session("ctl")
PlaceHolder1.Controls.Add(oCtl)
End If
End If
End Sub
Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
If Not IsPostBack Then
Dim oCtl As Object
oCtl = LoadControl("~/Controls/UserControl1.ascx")
oCtl.Id = "UserControl11"
PlaceHolder1.Controls.Clear()
PlaceHolder1.Controls.Add(oCtl)
Session("ctl") = oCtl
End If
End Sub
End Class
下面是用户控件的完整代码
Partial Class UserControl1
Inherits System.Web.UI.UserControl
Protected Sub Button1_Click(ByVal sender As Object, ByVal e As System.EventArgs) Handles Button1.Click
Label1.Text = "This is Text AFTER Post Back in User Control 1"
End Sub
End Class
既然你问了,我就这样写你的init事件。我将把加载事件留作练习:
Protected Sub Page_Init(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Init
If IsPostBack AndAlso Session("ctl") IsNot Nothing Then
Dim MyControl As Control = Session("ctl")
PlaceHolder1.Controls.Add(MyControl)
End If
End Sub
我也会想出一个比“mycontrol”更好的名字,但由于我不知道控件的作用,因此必须这样做。我不知道,但如果您通过编程连接按钮的事件处理程序,该怎么办?例如,在用户控件本身的代码隐藏中,在Init或Load(不确定)中:
如果这样做没有任何作用,我知道这样做效率较低,但是如果您不在会话中存储用户控件实例,并且每次都在Page_Init中重新创建它,会怎么样?您正在做的一些事情都是不需要的,可能会导致您的问题 这些是:
Default.aspx
<%@ Page Language="vb" AutoEventWireup="false" CodeBehind="Default.aspx.vb" Inherits="Test_User_Control._Default" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" >
<head runat="server"><title></title></head>
<body>
<form id="form1" runat="server">
<asp:PlaceHolder ID="PlaceHolder1" runat="server" />
</form>
</body>
</html>
UserControl1.ascx
<%@ Control Language="vb" AutoEventWireup="false" CodeBehind="UserControl1.ascx.vb" Inherits="Test_User_Control.UserControl1" %>
<asp:Label ID="Label1" Text="Before Button Press" runat="server" />
<asp:Button ID="Button1" Text="Push me" runat="server" />
我遇到了与您类似的问题,只是我没有使用会话来存储控件 在我的案例中,我将问题定位在这一行:
placeholder 1.Controls.Clear()
我所做的是创建一个子控件,并将它们添加到Page_Init上的父容器中,然后处理一些事件处理程序,然后在Page_PreRender上用更新的数据重新创建整个列表
我在本例中使用的解决方案是在页面周期的早期阶段创建一次控件集合。接受匈牙利前缀的点应记住这一点,以备将来使用。我将在下面的注释中粘贴完整的代码。非常感谢您的反馈,但这实际上并不能在控制范围内解决我的反馈问题
Partial Public Class _Default
Inherits System.Web.UI.Page
Private Sub Page_Init(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Init
Dim control As Control = LoadControl("~/UserControl1.ascx")
PlaceHolder1.Controls.Add(control)
End Sub
End Class
<%@ Control Language="vb" AutoEventWireup="false" CodeBehind="UserControl1.ascx.vb" Inherits="Test_User_Control.UserControl1" %>
<asp:Label ID="Label1" Text="Before Button Press" runat="server" />
<asp:Button ID="Button1" Text="Push me" runat="server" />
Public Partial Class UserControl1
Inherits System.Web.UI.UserControl
Private Sub Button1_Click(ByVal sender As Object, ByVal e As System.EventArgs) Handles Button1.Click
Label1.Text = "The button has been pressed!"
End Sub
End Class