动态创建的用户控件无法处理PostBack上的事件

时间:2008-09-18 14:00:51

标签: asp.net dynamic user-controls postback

我有一个用户控件,它使用页面初始化中的以下代码动态加载到页面中。

Dim oCtl As Object
oCtl = LoadControl("~/Controls/UserControl1.ascx")

oCtl.Id = "UserControl11"
PlaceHolder1.Controls.Clear()
PlaceHolder1.Controls.Add(oCtl)

用户控件还包含一个按钮,我无法捕获用户控件中的按钮单击。

9 个答案:

答案 0 :(得分:10)

你正在做的一些事情都是不需要的,可能会导致你的问题。

这些是:

  1. 无需在会话中存储控制对象。 Control本身应该使用ViewState和Session State来存储所需的信息,而不是整个实例。
  2. 创建控件时不应检查PostBack。每次都必须创建它以允许ViewState工作并且要连接事件。
  3. 加载ViewState后加载的控件经常无法正常运行,因此请尽可能避免在Page Load事件期间加载。
  4. 此代码适用于我:


    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" />
    

    UserControl1.ascx.vb

    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
    

答案 1 :(得分:5)

在.NET进入页面生命周期的“回发事件处理”步骤之前,您必须确保控件存在于页面上。由于控件是动态添加的,因此您必须确保在每个帖子上重新创建该控件,以便它可以找到触发事件的控件。

答案 2 :(得分:3)

确保在每次回发时加载控件 - 如果页面回发时控件不在控件树中,ASP.NET将不会引发按钮单击事件。

答案 3 :(得分:2)

我刚遇到类似的问题,除了在我的情况下我没有使用会话来存储控件。

就我而言,我将问题放在这一行:

PlaceHolder1.Controls.Clear()

我所做的是创建了一个子控件并将它们添加到Page_Init上的父容器中,然后处理了一些事件处理程序,之后在Page_PreRender上我再次使用更新的数据重新创建了整个列表。

我在这种情况下使用的解决方案是在页面循环的早期阶段创建一次控件集合。

答案 4 :(得分:1)

几个问题:

  1. 您在页面生命周期的哪个阶段加载控件?
  2. 事件处理程序代码在哪里?在控件本身或者您是否尝试将其连接到页面?
  3. 到目前为止你做了什么事情来结束这次活动?
  4. 最后,.Net的样式指南特别推荐使用oCtl中的o之类的hugarian前缀疣,您应该将其键入为Control而不是对象。

答案 5 :(得分:0)

以下是Page

的完整代码
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

以下是用户Control

的完整代码
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

答案 6 :(得分:0)

既然你问过,我会像这样写你的init事件。我将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

我还想出一个比'mycontrol'更好的名字,但是因为我不知道控件的作用是什么。

答案 7 :(得分:0)

我不知道没有尝试,但如果你以编程方式连接按钮的事件处理程序呢?例如,在用户控件本身的代码隐藏中,在Init或Load(不确定)中:

AddHandler Button1.Click, AddressOf Button1_Click

如果没有做任何事情,我知道效率较低,但如果你没有在Session中存储用户控件实例并且每次都在Page_Init中重新创建它会怎样呢?

答案 8 :(得分:-1)

您希望仅在非isPostBack

时加载控件