简体   繁体   中英

ASP.Net Page Lifecycle and dynamic controls

I'm am a little bit stuck in the ASP.Net's page lifecycle. This is my first ASP.Net project after many years of doing React so I might be missing something;)

Simplified code:

 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);
 }

The problem is that the "OnTileClicked" event works only on the first load and not after the postback. I believe it has something to do with the page lifecycle and registering the events after the Control events ( https://docs.microsoft.com/en-us/previous-versions/aspnet/ms178472(v=vs.100)?redirectedfrom=MSDN ).

If it is really the case, how do I then dynamically build pages from the code behind? Should I really create all the controls ( BuildOverview() and BuildRunsOverview()) and then conditionally show or hide them?

'Should I really create all the controls ( BuildOverview() and BuildRunsOverview()) and then conditionally show or hide them?'

Answer is: yes.
You don't dynamically build pages from code behind - at least its not that well supported in asp.net pages.
In your case you need the TilesContainer on every postback and attach the event handler to it, else the event won't be called. So it would be easier to put all your controls in the markup (.aspx) and just set them to Visible = false/true depending on your code. Controls you set to Visible = false won't be rendered on the client side, so at least no overhead there.
If you use custom-controls (I assume your TilesContainer is a custom-control), then you need to implement the Visible-property the right way, eg if your TilesContainer s main control is a Panel , override Visible and set the value there:

public override bool Visible 
{
    get { return base.Visible; }
    // set all neccessary controls visibility here
    set { this.pnlMain.Visible = base.Visible = value; }
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM