ASP.NET 2.0 released the web parts framework, which is a
framework that allows developers to create portal-based features in their
applications. It allowed the user to minimize or maximize content, remove
content from the window, or make it appear again. The data can be serialized to
a database using the internal personalization framework, which persist the data
to the asp.net tables.
To start with the docking framework, the docking container
is defined using the RadDockLayout control. The RadDockLayout control wraps all
the inner docking content together. I will explain the two events defined below
later.
Listing 6
<tel:RadDockLayout ID="rdLayout" runat="server"
onloaddocklayout="rdLayout_LoadDockLayout"
onsavedocklayout="rdLayout_SaveDockLayout">
</tel:RadDockLayout>
To setup the docking sections in the form, I often use a
table to do this. I use a table because it is easier to setup than to use
floating panels, which although popular, can have some display challenges (like
having the center content get pushed down below left and right columns). In
this example, the content appears in a two-column table and is shown below with
the docking zones defined.
Listing 7
<tel:RadDockLayout ID="rdLayout" runat="server"
onloaddocklayout="rdLayout_LoadDockLayout"
onsavedocklayout="rdLayout_SaveDockLayout">
<table cellspacing="0" border="0">
<thead>
<tr>
<th></th>
<th align="right">
<asp:Button ID="btnSave" runat="server" Text="Save" />
</th>
</tr>
</thead>
<tbody>
<tr>
<td>
<tel:RadDockZone ID="rdzLeftZone" runat="server" UniqueName="Left Zone"
HighlightedCssClass="DockHighlight">
</tel:RadDockZone>
</td>
<td>
<tel:RadDockZone ID="rdzRightZone" runat="server" UniqueName="Right Zone"
HighlightedCssClass="DockHighlight">
</tel:RadDockZone>
</td>
</tr>
</tbody>
</table>
</tel:RadDockLayout>
The table creates a two-column page using two RadDockZone
controls. The final output looks something like the following screenshot. Note
the use of a save button; I left out the save button from the screenshot, but
the save button allows the user to save the changes that they made to the UI.
Like the web parts framework, Telerik's RadControls for ASP.NET AJAX provides the ability to let the user save
changes they make to the database, and load them on the next page cycle. It
is easier to do this in the RadControls framework than in the .NET Framework, as we
will see soon.
Figure 3

Each of the three sections present (Welcome, Weather, and
Sports) are defined as RadDock controls. RadDock controls represent each
section that can be docked; it is analogous to the WebPart or GenericWebPart
control (which the GenericWebPart wraps any control defined within a
WebPartZone that does not implement IWebPart). The panels can be minimized,
maximized, closed, resized (using a drag handle), or moved to a different
RadDockZone, just like you can do in the web parts framework.
Listing 8
<tel:RadDock ID="rdSports" runat="server" DockMode="Docked" Title="Sports">
<ContentTemplate>
Your team lost, by a lot of points!
</ContentTemplate>
</tel:RadDock>
The RadDock control specifies the title of the docking
section using the Title property, and the content of the docking section using
the ContentTemplate property. These dock controls can be stacked within a
RadDockZone.
Listing 9
<tel:RadDockZone ID="rdzLeftZone" runat="server" UniqueName="Left Zone"
HighlightedCssClass="DockHighlight">
<tel:RadDock ID="rdWelcome" runat="server" DockMode="Docked" Title="Welcome">
<ContentTemplate>
Welcome to the site, designated to learn about telerik and
it's controls. I hope this site helps you understand
how to use telerik.
</ContentTemplate>
</tel:RadDock>
<tel:RadDock ID="rdWeather" runat="server" DockMode="Docked" Title="Weather">
<ContentTemplate>
It's raining all day, potential
</ContentTemplate>
</tel:RadDock>
</tel:RadDockZone>
Built into the docking is the ability to drag and drop these
docking controls across zones. This is built in for the user so that they can
rearrange the page as they see fit. Check out the screenshot below; in this
example, I am dragging the weather section from the left pane to the right
pane. Telerik's RadControls give the user a nice look.
Figure 4

Notice the light yellow background where the weather section
will be dropped into (highlighted by the light yellow background). This is
specified by the HighlightedCssClass name property defined for the RadDockZone
control.
Loading and Saving Content
The RadDockLayout persists changes made by the user by using
events. These two events, LoadDockContent and SaveDockContent, load and save
the content of the changes using a customized scheme. The code to load/save
events looks like the following:
Listing 10
protected void rdLayout_LoadDockLayout(object sender, Telerik.Web.UI.DockLayoutEventArgs e)
{
if (Session["DockContent"] == null)
return;
string[] content = (string[]) Session["DockContent"];
JavaScriptSerializer serializer = new JavaScriptSerializer();
e.Indices = serializer.Deserialize<Dictionary<string, int>>(content[0]);
e.Positions = serializer.Deserialize<Dictionary<string, string>>(content[1]);
}
protected void rdLayout_SaveDockLayout(object sender, Telerik.Web.UI.DockLayoutEventArgs e)
{
JavaScriptSerializer serializer = new JavaScriptSerializer();
string indices = serializer.Serialize(e.Indices);
string positions = serializer.Serialize(e.Positions);
Session["DockContent"] = new[] { indices, positions };
}
For now, the code uses the session to load/save the docking
layout. Telerik's RadDock requires a collection of indices and positions to reload the
docking layout. This is essentially a listing of docking layout containers and
their indices/positions (index 0 in the right dock container). The JavaScript
serializer is used to serialize the collections to a more meaningful format
because these two collections stored in the DockLayoutEventArgs event argument
are actually generic dictionaries. These are perfect for serialization and
deserialization.
While debugging, the indices looks like the following in the
dictionary, while saving the docking content.
Figure 5

The positions, however, look alternatively alike.
Figure 6

And so, these dictionaries contain important information for
us to use. When loading, the code converts the serialized string in JSON format
equivalent back to dictionaries. These strings look like:
Indices: {\"rdWelcome\":0,\"rdWeather\":1,\"rdSports\":0}
Positions: {\"rdWelcome\":\"ctl00_body_rdzLeftZone\",\"rdWeather\":\"ctl00_body_rdzLeftZone\",\"rdSports\":\"ctl00_body_rdzRightZone\"}
The JavaScriptSerializer object then deserializes the
content back into the dictionary for the Docking layout to use.