首页 > 解决方案 > ASP.Net 页面生命周期和动态控件

问题描述

我有点卡在 ASP.Net 的页面生命周期中。这是我从事 React 多年后的第一个 ASP.Net 项目,所以我可能会遗漏一些东西;)

简化代码:

 protected void Page_Load(object sender, EventArgs e)
 {
    BuildView();
 }

 private void BuildView()
 {
    switch (pageViewMode.Value)
    {
        case "Overview": BuildOverview(); break;
        case "Runs": BuildRunsOverview(); break;
    }
 }

 private void BuildOverview()
 {
    var tilesContainer = new TilesContainer();
    tilesContainer.OnTileClicked += (InfoTile targetTile) =>
            {
                pageViewMode.Value = targetTile.Value;
                BuildView();
            };
    rootElement.Controls.Add(tilesContainer);
 }

问题是“OnTileClicked”事件仅在第一次加载时有效,在回发后无效。我相信它与页面生命周期和在控制事件之后注册事件有关(https://docs.microsoft.com/en-us/previous-versions/aspnet/ms178472(v=vs.100)?redirectedfrom =MSDN)。

如果真的是这样,我该如何从后面的代码动态构建页面?我真的应该创建所有控件(BuildOverview() 和 BuildRunsOverview())然后有条件地显示或隐藏它们吗?

标签: c#asp.net

解决方案


“我真的应该创建所有控件(BuildOverview() 和 BuildRunsOverview()),然后有条件地显示或隐藏它们吗?”

答案是:是的。
您不会从后面的代码动态构建页面 - 至少它在 asp.net 页面中没有得到很好的支持。
在您的情况下,您需要TilesContainer每次回发并将事件处理程序附加到它,否则不会调用该事件。因此,将所有控件放在标记 (.aspx) 中并Visible = false/true根据您的代码设置它们会更容易。您设置的控件Visible = false不会在客户端呈现,因此至少没有开销。
如果您使用自定义控件(我假设您TilesContainer是自定义控件),那么您需要以正确的方式实现 Visible-property,例如,如果您TilesContainer的主控件是 a Panel,则覆盖Visible并在那里设置值:

公共覆盖布尔可见
{
    得到{返回基地。可见;}
    // 在这里设置所有必要的控件可见性
    设置 { this.pnlMain.Visible = base.Visible = 值;}
}

推荐阅读