1

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?

Ciamas
  • 41
  • 2
  • 7
  • If i remember this right (and it's been a while) you need to check IsPostBack() and only call BuildView() if it isn't a postback – Mikey Mouse Jun 26 '20 at 09:22
  • If I don't build if it isn't postback I don't see anything on the page as the page itself has only the rootElement div there. – Ciamas Jun 26 '20 at 09:24
  • Maybe you wanna do something like this https://stackoverflow.com/a/8587602/1098100 – Mikey Mouse Jun 26 '20 at 09:25
  • This is a `Web forms` project, right? In that case, I agree with the answer by @Homungus below. Using dynamically created controls in web forms is possible, but getting it to work right is a pain in the backside. If you have anything more than a trivial use case, you will eventually find yourself re-inventing the page state management that the web forms system does out of the box for you if you just add the controls in the `.aspx` file. – user1429080 Jun 26 '20 at 10:32

1 Answers1

2

'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; }
}
Homungus
  • 1,114
  • 1
  • 10
  • 20
  • I moved the controls to the html and it is working now, thanks! One question though. Why is setting Visible = False not workign in my controls? I ended up with if (!this.Visible) { return; } in RenderControl but don't really like it:] – Ciamas Jun 29 '20 at 06:59
  • I updated the answer to point you in the right direction. – Homungus Jun 29 '20 at 07:32