Practical ASP.NET
Dynamically Generate Complex Pages with the MultiView
The MultiView control allows you to swap sets of controls on and off the page. But the MultiView control also makes it easier for you to generate new page content and add it at run time.
This week I'm looking at a problem that you probably don't have: dynamically changing the controls on the page at runtime. The scenario that I'm addressing is when, depending on the choices that the user makes, you want to add or remove multiple controls on the page. And, just to make the problem a little more interesting, I'm going to assume that you can't predict at design time what combination of controls are going to be required (or that there's so many different combinations that you can't set them all up at design time).
You don't have to use the techniques described here: You could just send the user to a different page with the controls the user needs. However, to integrate the information that the user enters on a variety of pages is... complicated. If you can keep all the controls on the same page, you can access them from code on the page without using, for instance, the Session object.
Design-Time Solutions
In the bad old days of ASP.NET 1.0, developers would handle this by dropping multiple Panels on the page and putting different sets of controls in different Panels. By manipulating the Visible properties of the various Panel controls, the developer could control which set of controls were visible at any one time, dynamically changing the page content at run time.
ASP.NET 2.0 provided the MultiView control. Instead of adding multiple Panels to the page, you add multiple View controls to a MultiView. Like a Panel, each View control can hold one or more controls. At runtime, you can use the MultiView's ActiveViewIndex property to control which View will be displayed (and be guaranteed that only one of the Views will be displayed at any one time).
Adding Your Own Content
However, both of these solutions assume that you can determine at design time what controls should be in each view. But what if you don't know what content will be required at run time? In that case, you'll have to create your controls in code and add them to the page.
If you have only one set of controls to display, you can create a table, add controls to the table, and then add the table to the page (after setting the table's CssClass property to a CSS rule that will control your table's appearance and layout). This example creates a table with one row and two cells holding a label and a textbox:
Dim tbl As New Table
Dim tr As New TableRow
tbl.Rows.Add(tr)
Dim lbl As New Label
lbl.Text = "Student Name"
Dim tdLbl As New TableCell
tdLbl.Controls.Add(lbl)
tr.Cells.Add(tdLbl)
Dim txt As New TextBox
txt.ID = "vw01"
Dim tdTxt As New TableCell
tdTxt.Controls.Add(txt)
tr.Cells.Add(tdTxt)
Now comes the problem: Adding your controls to the page. At the very least, you have to add your Table to the form1 element in the page, which is normally the fourth control in the page. The code to add your Table to the page would be:
Me.Controls(3).Controls.Add(tbl)
If you're using a Master Page, this code will be considerably more complicated. More likely, then, you'll add a Panel to the page at design time and add your table to the Panel at runtime:
Me.Panel.Controls.Add(tbl)
Multiple Views
But if you need to add multiple sets of controls to the page, things are going to get complicated. Here's where the MultiView is useful. Rather than going back to managing Panels, you can create Views for each different set of controls you need, load the Views with controls each need, and then add the Views to a MultiView.
To use a MultiView and Views, in the previous code just replace the line that adds the table to the Page with code that creates a View, adds your table to the View, and then adds the View to a MultiView on the page:
Dim vw As New View
vw.Controls.Add(tbl)
Me.MultiView1.Views.Add(vw)
At this point, you can decide which View you want to actually display. If you want to display the View that you just added, you can use the MultiView's SetActiveView method, passing the View you just created:
Me.MultiView1.SetActiveView(vw)
There is one wrinkle: You must create and add your controls in the Page's PreInit event, otherwise ASP.NET will generate an error on postback.
As I said at the start, you probably don't need this solution. But when you need to dynamically add different combinations of controls to a page, the MultiView can simplify what would otherwise be a complex problem.
About the Author
Peter Vogel is a system architect and principal in PH&V Information Services. PH&V provides full-stack consulting from UX design through object modeling to database design. Peter tweets about his VSM columns with the hashtag #vogelarticles. His blog posts on user experience design can be found at http://blog.learningtree.com/tag/ui/.