1

From research, the answer to my question seems to be a resounding no.

From Rob de la Cruz's answer here and Jonathan Wood's answer here, it seems that the only way to do it is to use JavaScript. Sadly, I don't have the necessary skill level to implement their solutions and I'm not completely sure it will work for my situation anyway. See what you think:

What I have (using asp.net and C# in VS2019) is a treeview control which:

  • 1.1 At the first level, displays the names of customers.
  • 1.2 Expand a customer node and the next level displays a list of sales order numbers for that customer.
  • 1.3 Expand a sales order node and the third and final level displays a list of the sale items belonging to that particular sales order.

Pretty standard stuff I should imagine. Now, also pretty standard is that, when a node is clicked a procedure will make visible a formview which displays information about that object. When a customer node is clicked it will display the customer formview. When a sales order node is clicked it will display a sales order formview. When a sale item node is clicked... you can probably guess what it displays then.

And this is where things start to go off the rails. When a node is clicked, it's Value property is stored in a variable called _id. This variable is then stored in ViewState. When the PostBack happens, the idea is that the Page_Load event will read the value of _id from ViewState, run the showFormViews() procedure and display the relevant formview. I have it laid out like this:

protected void Page_Load(object sender, EventArgs e)
{
    if (ViewState["_id"] == null)
    {
        _id = "";
    }
    else
    {
        _id = Convert.ToString(ViewState["_id"]);
    }
    if (!IsPostBack)
    {
        fillTreeView;
        tv.CollapseAll();
    }
    showFormViews();
}

and when a node is clicked:

protected void tv_SelectedNodeChanged(Object sender, EventArgs e)
{
    // (a) PostBack occurs and Page_Load is run *before* _id is set and stored in ViewState
    _id = tv.SelectedNode.Value;
    ViewState.Add("_id", _id);
    showFormViews();
    // (b) would be great to be able to fire off a PostBack programmatically right here!
}

(the .aspx markup is just a TreeView and three FormViews linked to ObjectDataSources)

As I now know from this helpful page:

"The initialisation part of the page lifecycle will execute before the event handler of the control that caused the post back. Therefore the code in the page’s Init and Load event handler will execute before the code in the event handler for the button that the user clicked."

As written at line (a) above, when the treeview node is clicked, the page is posted back and Page_Load is run whilst _id is still null. Because _id is null the showFormViews() procedure hides all of the formviews.

Then the SelectedNodeChanged event fires, _id is set and the showFormViews() procedure sets the relevant formview to visible. But of course, by now all of the controls have been rendered and so... nothing happens.

Being able to somehow fire a PostBack at line (b) would work out wonderfully. Page_Load would fire and run showFormViews() but this time with _id being what it should be.

Various variations at line (b) of:

Server.Transfer("samePage.aspx");
// or
Response.Redirect(Request.RawUrl, false);

don't work because they destroy ViewState (unless someone knows different?) so _id is back to being null again.

So if you can't fire off a PostBack in C# and if I can't work out how to implement the solutions by the two posters above (or even if they will be appropriate in this situation), is there any way I can restructure the page to make this - a fairly common pattern I would imagine - work (and please don't suggest MVC - I tried learning that and still have the nightmares!).

Many thanks in advance,

Abdul Haseeb
  • 514
  • 4
  • 13
  • 1
    A PostBack is nothing more that the front-end code triggering a reload of the page, running the `Page_Load` and the method specified in the aspx. So in C# code you can always do `Button1_Click(null, null);` or `tv_SelectedNodeChanged(null, null);` from somewhere in the code. Or I am very misunderstanding the quesion... – VDWWD Aug 24 '20 at 20:04
  • Hi VDWWD, no you're probably not misunderstanding the question. I think I was misunderstanding the problem. I have no idea why but it's just started working. I don't see how it can... but it does, which is good enough for me! Thanks very much for commenting though and I didn't know you could call an event like Button1_Click(null, null); so I've learnt something there too. – FredAndBarney Aug 25 '20 at 10:51

1 Answers1

0

You can call in your PageLoad the method used to fill the ViewState... Like:

    protected void Page_Load(object sender, EventArgs e)
{
    if (ViewState["_id"] == null)
    {
        _id = "";
    }
    else
    {
        _id = Convert.ToString(ViewState["_id"]);
        tv_SelectedNodeChanged(null, null);
    }

    if (!IsPostBack)
    {
        fillTreeView;
        tv.CollapseAll();
    }
} 
  • 1
    Hi Renato, as I've written in reply to VDWWD's comment above, it's suddenly all started working for no good reason that I can see! Thanks very much for your comment though and for showing me a way of calling an event I wasn't aware of before. – FredAndBarney Aug 25 '20 at 10:54