我有一个用户控件,使用以下代码在页面的Init中动态加载。
Dim oCtl As Object
oCtl = LoadControl("~/Controls/UserControl1.ascx")
oCtl.Id = "UserControl11"
PlaceHolder1.Controls.Clear()
PlaceHolder1.Controls.Add(oCtl)
用户控件还包含一个按钮,但我无法在用户控件内捕获按钮点击事件。
我有一个用户控件,使用以下代码在页面的Init中动态加载。
Dim oCtl As Object
oCtl = LoadControl("~/Controls/UserControl1.ascx")
oCtl.Id = "UserControl11"
PlaceHolder1.Controls.Clear()
PlaceHolder1.Controls.Add(oCtl)
您正在做的几件事情既没有必要,而且可能会导致问题。
这些是:
这段代码对我有效:
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>
Default.aspx.vb
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
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" />
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
在.NET进入页面生命周期的“Postback事件处理”步骤之前,您必须确保控件存在于页面上。由于控件是动态添加的,因此您必须确保在每次回传时重新创建该控件,以便它可以找到控件来触发事件。
确保在每次回发时加载控件 - 如果控件不在页面回发时的控件树中,ASP.NET将无法引发按钮单击事件。
我刚刚遇到了和你类似的问题,只是在我的情况下,我没有使用会话来存储控件。
在我的情况下,我发现问题出在这一行:
PlaceHolder1.Controls.Clear()
我的做法是在 Page_Init 中创建子控件并将它们添加到父容器中,然后处理一些事件处理程序,在 Page_PreRender 上重新创建整个列表以更新数据。
在这种情况下,我使用的解决方案是在页面周期的早期阶段创建控件集合。
几个问题:
最后,.Net的样式指南特别建议不要使用任何匈牙利前缀,例如oCtl中的o,而应该将其键入为Control而不是对象。
AddHandler Button1.Click, AddressOf Button1_Click
如果那样做没有任何作用,我知道这样做效率会降低,但是如果您不将用户控件实例存储在会话中,并且每次都在Page_Init中重新创建它呢?
这是页面的完整代码
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
既然你问了,我会这样编写您的初始化事件。Load事件就留给你做练习吧:
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
你想在非PostBack时才加载控件