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

时间:2011-03-14 14:39:01

标签: asp.net user-controls

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

根本没有触发事件

据我所知,我需要在仪表板页面的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);
        }
    }

2 个答案:

答案 0 :(得分:0)

我以前在Page_Load中成功加载了控件。我发现我唯一需要注意的是确保如果我进行了回发,则在后续的page_load中加载相同的控件以确保视图状态不会被破坏...所有事件等都按预期工作。在我的情况下,控制流程最终结果如下:

page_load - 加载控件

(做一些导致回发和事件x开火的事情)

page_load - 确保加载控件

event_x - 清除控制a,加载控制b

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

page_load - 确保加载控件b ...

这意味着加载你完全有意丢弃的控件,但这是我找不到腐败视图状态的唯一方法......

如果你有一个包含PlaceHolder1和Label1的页面,那么下面的代码会导致按钮点击事件正常启动:

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

WebUserControl代码背后:

protected void Button1_Click(object sender, EventArgs e)
{
    Label1.Text = "Clicked Button";
}

加载子控件的父控件:

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

答案 1 :(得分:0)

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