views:

288

answers:

4

Suppose I have a treeview, where each treenode contains an id for a different set of user controls. When the user clicks a node, these controls should be loaded to the page. As I understand the ASP page life cycle, dynamic controls should be added in the initialization stage, and postback events will fire later on.

So if the treeview click event happens after I need to add my controls, how do I dynamically add controls based on user postback events?


Edit: I tried the suggestion from ArronLS:

What I did was add the node value to the session array, and use that when I do the init to choose which form elements to load to the controls of a placeholder control. On the treeview click event, I update the node in the session array, clear the old form elements in the placeholder, and add the new form elements to the controls. When the page is loaded again, it should now find the node at init time, so viewstate problems would be circumvented.

Now I haven't fully tested this yet, but there was another similar post that talks about the problems that might result with the viewstate. They suggest a solution that polls the Request[] part of the context (in their case the dropbox) within the Init control, manually handling some of the postback functionality.

My new question is how to I access the selected node in the treeview using the Request array?

+1  A: 

This may not be an answer to your direct question, but since I've never found an answer myself, here's the workaround I've used.

The approach I've always used when working with a TreeView is to declare the controls in the aspx page once, and then on the click event, bind the controls the the data based on the id. If necessary, you can initially set the visibility to visible="false" and change it when bound. This approach works nicely because it avoids just the conundrum you're describing.

If you're not opposed to giving up on treeviews, a nested repeater approach works well, too.

David Stratton
Thanks for the suggestion. I'm somewhat hesitant to load all configurations every time, since my tree can be arbitrarily large, configurations could be unique, and that may create significant overhead. I've never worked with a nested repeater before, I'll look into that.
tbischel
A: 

The consequence of not loading the controls in init is that if there are changes to properties in the view state, these will not get persisted to the controls. For example, if on the first request of the page, you dynamically create controls in init, then on the post back you create them again in init, then after init, any property values in viewstate get applied to the control.

So if you created the control initially in a treeview click event, I would guess that should be fine, because there is not yet any viewstate accumulated to apply to the control since it was just created. However, I am not sure if this will cause the control to not save viewstate. You'd have to experiment with that.

On subsequent postbacks after the first, now you will need to create the control in init for accumulated viestate to be applied to it, so you'll need some mechanism to "remember" that you created the control once before, initially in response to the click event, and then on subsequent postbacks create the control again in init. You have to recreate the control on each request, if you didn't know that.

So the question becomes how important is the viewstate for the control.

Edit: I will also add that I am not entirely sure if there would be other consequence other than how this affects viewstate.

AaronLS
Thanks, I'll give this a try. To summarize what I think you are saying is: first time a node is clicked, load it via the postback event and persist the configuration somehow. Then, in subsequent postbacks/page loads, load the persisted node in the init function.
tbischel
A: 

Just throwing out another thought, hoping to get some more feedback...

I could use the postback event to define the selected value in the session array, and then force the page to redirect to itself. Then, the init that the user sees will effectively be done after the event handler has fired.

Seems like a bad idea, so I'm hoping for something else.

tbischel
A: 

If I've understood you correctly you want different content shown for each tree node. I'm assuming theres the treeview on the left and some content area in the middle.

From a UI perspective I normally solve this by using a MultiView where each individual View is a seperate usercontrol with the required content. The treenode click event simply changes the MultiView ActiveIndex contained in the Node value property (ID is stored in the DataItem) and you simply switch out the content area.

Generally, even if the tree nodes are dynamically generated, from data for example, there will only ever be a finite amount of "Node View" usercontrols that you need to define.

Note. Be careful when using the MultiView control as all Views contained are loaded during the page life-cycle so dont put any "heavy-lifting" into Page_Load etc.

bic
A good tutorial using multiviews dynamically. I'll have to test this for viewstate issues. http://visualstudiomagazine.com/articles/2009/10/22/generate-complex-pages-with-multiview.aspx
tbischel