Adding Controls Inside Dynamically Created Docks
When implementing a dynamic personalized Portal site using the techniques described in Dynamically Creating RadDock Controls, the dynamically created controls often contain specialized custom controls. When re-creating the RadDock controls after a postback, the application needs to re-create these custom controls as well. The following example shows one way to accomplish this.
-
Create a new AJAX-enabled Web application.
-
In order to add some custom controls to your application, locate the "Live Demos\Dock\Examples" folder under your installation directory and drag the "Default" folder from there to your solution in the Solution Explorer. Delete the "Default.html", "DefaultCS.aspx", and "DefaultVB.aspx" files. The Solution Explorer should looks something like the following screen shot:
-
To let the user select a control to add to the page, drag a DropDownList from the toolbox onto your page. Click on the ellipsis button next to its Items property, and add five items, setting the following properties:
-
Text="ExchangeRates.ascx", Value="~/Default/ExchangeRates.ascx", Selected=True
-
Text="Horoscopes.ascx", Value="~/Default/Horoscopes.ascx"
-
Text="News.ascx", Value="~/Default/News.ascx"
-
Text="Pictures.ascx", Value="~/Default/Pictures.ascx"
-
Text="Weather.ascx", Value="~/Default/Weather.ascx"
-
-
Drag a Button from the toolbox onto the page, and set its Text property to "Add Dock";
-
Add a RadDockLayout with a few RadDockZone controls inside it.
-
Just like in the Dynamically Creating RadDock Controls topic, add a property for storing the current dock states:
-
At the top of the code behind for your Web page, add two new using statements (C#) or Imports statements (VB) for System.Collections.Generic and Telerik.Web.UI:
C#using System.Collections.Generic; using Telerik.Web.UI;
VBImports System.Collections.Generic Imports Telerik.Web.UI
-
Add the following property definition to the class definition of your Web page:
C#//Store the info about the added docks in the session. private List<DockState> CurrentDockStates { get { List<DockState> _currentDockStates = (List<DockState>)Session["CurrentDockStates"]; if (Object.Equals(_currentDockStates, null)) { _currentDockStates = new List<DockState>(); Session["CurrentDockStates"] = _currentDockStates; } return _currentDockStates; } set { Session["CurrentDockStates"] = value; } }
VB'Store the info about the added docks in the session. Private Property CurrentDockStates() As List(Of DockState) Get Dim _currentDockStates As List(Of DockState) = _ DirectCast(Session("CurrentDockStates"), List(Of DockState)) If [Object].Equals(_currentDockStates, Nothing) Then _currentDockStates = New List(Of DockState)() Session("CurrentDockStates") = _currentDockStates End If Return _currentDockStates End Get Set(ByVal value As List(Of DockState)) Session("CurrentDockStates") = value End Set End Property
-
-
Add a Click event handler to the Button on the Web page. This event handler creates a new RadDock control, creates a custom control inside it, and adds it to the first RadDockZone control. Note that the Tag property is used to store the information needed to create the custom control:
C#private RadDock CreateRadDock() { int docksCount = CurrentDockStates.Count; RadDock dock = new RadDock(); dock.ID = string.Format("RadDock{0}", docksCount); dock.Title = string.Format("Dock {0}", docksCount); dock.UniqueName = Guid.NewGuid().ToString(); dock.Width = Unit.Pixel(300); return dock; } protected void Button1_Click(object sender, EventArgs e) { RadDock dock = CreateRadDock(); dock.Tag = DropDownList1.SelectedValue; LoadWidget(dock); RadDockZone1.Controls.Add(dock); } private void LoadWidget(RadDock dock) { if (string.IsNullOrEmpty(dock.Tag)) return; Control widget = LoadControl(dock.Tag); dock.ContentContainer.Controls.Add(widget); }
VBPrivate Function CreateRadDock() As RadDock Dim docksCount As Integer = CurrentDockStates.Count Dim dock As New RadDock() dock.ID = String.Format("RadDock{0}", docksCount) dock.Title = String.Format("Dock {0}", docksCount) dock.UniqueName = Guid.NewGuid().ToString() dock.Width = Unit.Pixel(300) Return dock End Function Protected Sub Button1_Click(ByVal sender As Object, ByVal e As EventArgs) Handles Button1.Click Dim dock As RadDock = CreateRadDock() dock.Tag = DropDownList1.SelectedValue LoadWidget(dock) RadDockZone1.Controls.Add(dock) End Sub Private Sub LoadWidget(ByVal dock As RadDock) If String.IsNullOrEmpty(dock.Tag) Then Return End If Dim widget As Control = LoadControl(dock.Tag) dock.ContentContainer.Controls.Add(widget) End Sub
-
Add code to save and load the state of dynamically created controls when a postback occurs.
-
Add a SaveDockLayout event handler to the RadDockLayout component. This event handler calls the RadDockLayout.GetRegisteredDocksState method to obtain the current list of dock states and saves the list to the CurrentDockStates property.
C#protected void RadDockLayout1_SaveDockLayout(object sender, DockLayoutEventArgs e) { CurrentDockStates = RadDockLayout1.GetRegisteredDocksState(); }
VBProtected Sub RadDockLayout1_SaveDockLayout( _ ByVal sender As Object, _ ByVal e As DockLayoutEventArgs) _ Handles RadDockLayout1.SaveDockLayout CurrentDockStates = RadDockLayout1.GetRegisteredDocksState() End Sub
-
Add a Page_Init event handler that recreates the RadDock controls (including their child custom controls) after a postback:
C#protected void Page_Init(object sender, EventArgs e) { for (int i = 0; i < CurrentDockStates.Count; i++) { RadDock dock = new RadDock(); dock.ID = string.Format("RadDock{0}", i); dock.ApplyState(CurrentDockStates[i]); RadDockLayout1.Controls.Add(dock); LoadWidget(dock); } }
VBProtected Sub Page_Init(ByVal sender As Object, ByVal e As EventArgs) Handles Me.Init Dim i As Integer For i = 0 To CurrentDockStates.Count - 1 Dim dock As RadDock = New RadDock() dock.ID = String.Format("RadDock{0}", i) dock.ApplyState(CurrentDockStates(i)) RadDockLayout1.Controls.Add(dock) LoadWidget(dock) Next i End Sub
-
Add a LoadDockLayout event handler so that the RadDockLayout can restore the layout:
C#protected void RadDockLayout1_LoadDockLayout(object sender, DockLayoutEventArgs e) { foreach (DockState state in CurrentDockStates) { e.Positions[state.UniqueName] = state.DockZoneID; e.Indices[state.UniqueName] = state.Index; } }
VBProtected Sub RadDockLayout1_LoadDockLayout( _ ByVal sender As Object, _ ByVal e As DockLayoutEventArgs) _ Handles RadDockLayout1.LoadDockLayout For Each state As DockState In CurrentDockStates e.Positions(state.UniqueName) = state.DockZoneID e.Indices(state.UniqueName) = state.Index Next state End Sub
-
To improve performance, you may want to use a hidden update panel for saving state when minimizing, moving and closing docks. This way the docks state is saved faster as there is no need to update the docking zones. See My Portal for a live example that uses this technique.