在动态加载的ASP.NET用户控件上连接事件?

在动态加载的ASP.NET用户控件上连接事件?,asp.net,user-controls,Asp.net,User Controls,对于“仪表板”模块,我需要在用户进入页面(角色等)时根据条件动态加载用户控件。问题是根本没有从控件触发事件 据我所知,我需要在仪表板页面的OnPreInit方法中加载控件,但是在初始化的这一点上,我无法获得对占位符控件的引用(即,我得到一个NullReferenceException);具有讽刺意味的是,尝试通过Page.FindControl动态加载占位符会给我带来StackOverflowException 我也尝试过在PreRender和OnInit中加载控件,但是控件中的事件没有正确连接

对于“仪表板”模块,我需要在用户进入页面(角色等)时根据条件动态加载用户控件。问题是根本没有从控件触发事件

据我所知,我需要在仪表板页面的OnPreInit方法中加载控件,但是在初始化的这一点上,我无法获得对占位符控件的引用(即,我得到一个NullReferenceException);具有讽刺意味的是,尝试通过
Page.FindControl
动态加载占位符会给我带来StackOverflowException

我也尝试过在PreRender和OnInit中加载控件,但是控件中的事件没有正确连接,不会触发

代码基本上是这样的:

    // this does not work; if I try to access the placeholder control itself
    // ("phDashboardControls") I get a NullReferenceException, if I try 
    // Page.FindControl("phDashboardControls") I get a StackOverflowException
    protected override void OnPreInit(EventArgs e)
    {
        base.OnPreInit(e);
        Control ph = Page.FindControl("phDashBoardControls"); // Placeholder
        if (ph != null)
        {
           // GetControlsToLoad just instantiates the controls and returns 
           // an IList<Control>.  Eventually it will have logic to 
           // determine which control needs to be loaded based on user role etc.
           foreach (Control control in GetControlsToLoad())                
           {
               ph.Controls.Add(control);
           }
        }
    }

    // IModularControl is a custom interface defining a single 
    //  Initialize method to set up a control...
    private void Page_Load(object sender, EventArgs e)
    {
        foreach (Control control in this.phDashboardControls.Controls)
        {
            if (control is IModularControl)
                ((IModularControl)control).Initialize(this.CompanyID);
        }
    }
//这不起作用;如果我尝试访问占位符控件本身
//(“phDashboardControls”)如果我尝试,会得到一个NullReferenceException
//我得到一个StackOverflowException
受保护的重写void OnPreInit(EventArgs e)
{
基于preinit(e);
控件ph=Page.FindControl(“phDashBoardControls”);//占位符
如果(ph!=null)
{
//GetControlsToLoad只是实例化控件并返回
//一个IList。最终它将有逻辑
//根据用户角色等确定需要加载的控件。
foreach(GetControlsToLoad()中的控件)
{
添加(对照组);
}
}
}
//IModularControl是一个自定义接口,用于定义单个
//初始化方法以设置控件。。。
私有无效页面加载(对象发送方,事件参数e)
{
foreach(此.phDashboardControls.Controls中的控件)
{
if(控制为IModularControl)
((IModularControl)控件)。初始化(this.CompanyID);
}
}

我已经成功地在加载之前的页面中动态加载控件。我发现唯一需要注意的是,如果我进行回发,在随后的页面加载中会加载相同的控件,以确保视图状态不会损坏。。。所有活动等均按预期进行。在我的例子中,控制流最终是这样的:

页面_加载-加载控制a

(执行导致回发和事件x触发的操作)

页面加载-确保加载控件a

事件x-清除控制a、负载控制b

(做一些导致回发的事情)

页面加载-确保加载控件b

这意味着加载您打算完全丢弃的控件,但这是我找到的唯一不损坏viewstate的方法

如果页面中有占位符1和标签1,则以下代码会导致按钮单击事件正常触发:

    protected void Page_Load(object sender, EventArgs e)
{
    var dynamicButton = new Button() { Text = "Click me" };
    dynamicButton.Click +=new EventHandler(dynamicButton_Click);
    PlaceHolder1.Controls.Add(dynamicButton);
}

void dynamicButton_Click(object sender, EventArgs e)
{
    Label1.Text = "Clicked button";
}
与用户控件的行为相同:

WebUserControl ascx:

<%@ Control Language="C#" AutoEventWireup="true" CodeFile="WebUserControl.ascx.cs"   Inherits="WebUserControl" %>
<asp:Label ID="Label1" runat="server" Text="Label"></asp:Label>
<asp:Button ID="Button1" runat="server" Text="Click Me" onclick="Button1_Click" />
加载子控件的父控件:

protected void Page_Load(object sender, EventArgs e)
{
    var dynamicControl = Page.LoadControl("~/WebUserControl.ascx");
    PlaceHolder1.Controls.Add(dynamicControl);
}

仅供参考,该问题与验证有关;事件没有正确触发,因为一些验证控件(有一吨)没有配置为仅应用于该控件。

Hmm。。除了调用代码不是为了只在回发时加载控件,所以每次都应该触发并连接控件。控件加载得很好,只需单击按钮什么也不做。它们是用户控件,不是ASP.NET控件,这会有所不同吗?在这种情况下,EventHandler将设置在哪里?将测试它并让您知道。谢谢:)好吧,我试着把它们自己加载到页面上,而不是动态加载(事实证明,动态不是必需的)。如果我在页面上只有一个控件,它就可以正常发布。当我添加一个包含表单的控件(并填充一些控件)时,一切都不起作用。问题似乎出在这个特定控件中(其他控件工作正常)。
protected void Page_Load(object sender, EventArgs e)
{
    var dynamicControl = Page.LoadControl("~/WebUserControl.ascx");
    PlaceHolder1.Controls.Add(dynamicControl);
}