Just as the Literal control allows you to inject HTML into a page at runtime, the PlaceHolder control allows you to inject new controls into a page, at a specific location, at runtime. Imagine that you have a table full of links, and you want to insert the series of links into a page between to static paragraphs of text. You don't want to render the entire page at runtime, only the list of links.
No problem the PlaceHolder control comes to the rescue (working with its pal, the Literal control). We've used this technique to generate the content for Main.aspx in the sample project shown in Figure 22.5. At design time, there's really nothing on this page except a Label control and a single PlaceHolder control (see Figure 22.6).
Figure 22.5. You can generate any control at runtime and use the PlaceHolder control to place the new control at a known location on the page.
Figure 22.6. The sample page doesn't contain much until runtime.
The PlaceHolder control provides a collection property, the Controls property, that allows you to work with and add to the collection of controls contained within the PlaceHolder control. (The PlaceHolder control isn't the only control that provides a Controls collection the GroupBox, RadioButtonList, and CheckBoxList controls, for example, also allow you to work with the subcontrols contained within the control. The PlaceHolder control, however, is the best control to use if you want to generate new content on a page at runtime.)
To add a new control at runtime, you can simply instantiate the type of control you want, set the properties you need, and then add the new control to the Controls collection of the PlaceHolder control. For example, the Main.aspx page needs four HyperLink controls, with <p> elements (paragraph breaks) between them. The page contains the AddLink procedure, shown in Listing 22.2, which adds a single link and a <p> element afterwards:
Listing 22.2 Add HyperLink Controls to the Page Dynamically
Private Sub AddLink( _ ByVal NavigateURL As String, _ ByVal Text As String, _ ByVal ID As String) Dim hyp As New HyperLink() Dim lit As New Literal() With hyp .NavigateUrl = NavigateURL .Text = Text .ID = ID End With plcHyper.Controls.Add(hyp) lit.Text = "<p>" plcHyper.Controls.Add(lit) End Sub
The AddLink procedure starts out by instantiating a new HyperLink control and a new Literal control:
Dim hyp As New HyperLink() Dim lit As New Literal()
The procedure sets properties of the HyperLink control using parameters passed into the procedure:
With hyp .NavigateUrl = NavigateURL .Text = Text .ID = ID End With
Once the hyperlink is all set up, the code adds the control to the Controls collection of the PlaceHolder control on the page:
The code then sets the Text property of the Literal control and adds it to the PlaceHolder, as well:
lit.Text = "<p>" plcHyper.Controls.Add(lit)
The Page_Load procedure calls the AddLink procedure four times, once for each link it must add:
Private Sub Page_Load( _ ByVal sender As System.Object, _ ByVal e As System.EventArgs) _ Handles MyBase.Load If Not Page.IsPostBack Then AddLink("ListControls.aspx", _ "List Controls", "hypListControls") AddLink("CalendarControl.aspx", _ "Calendar Control", "hypCalendarControl") AddLink("AdRotatorControl.aspx", _ "Ad Rotator Control", "hypAdRotator") AddLink("LiteralControl.aspx", _ "Literal Control", "hypLiteralControl") End If End Sub
Although the sample page uses hard-coded links, your page might use link information pulled from a database, thus allowing you to create totally dynamic pages at runtime.