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,