Ciamas
Ciamas

Reputation: 41

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://learn.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?

Upvotes: 1

Views: 96

Answers (1)

Homungus
Homungus

Reputation: 1114

'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, e.g. if your TilesContainers 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; }
}

Upvotes: 2

Related Questions