Hi,
I'm messing around with creating a dock page which has several selectable controls which you can add to a single dock. I got this working fine with session objects, but am struggling trying to move it to use cookies. Could you help?
The problem seems to be that it looses the controls from the dock after the postback. In the example I was using with sessions, there was some code in the page_load which recreated the docks, I'm not really sure how to do this from the information that is stored in the cookie. Should I be looking at serializing the dockstate dictionary, or recreating the docks from the cookie information? Heres the code I've got:
Thanks for any suggestions,
Lee.
It also uses a master page and a web user control, but these have nothing in them except some html to test with.
ASPX:
<%@ Page Language="C#" MasterPageFile="~/MasterPage.master" AutoEventWireup="true" CodeFile="Default2.aspx.cs" Inherits="Default2" Title="Untitled Page" %>
<%@ Register src="WebUserControl.ascx" tagname="SampleWidget" tagprefix="uc1" %>
<%@ Register assembly="Telerik.Web.UI" namespace="Telerik.Web.UI" tagprefix="telerik" %>
<asp:Content ID="Content1" ContentPlaceHolderID="head" Runat="Server">
</asp:Content>
<asp:Content ID="Content2" ContentPlaceHolderID="ContentPlaceHolder1" Runat="Server">
<asp:ScriptManager ID="ScriptManager1" runat="server">
</asp:ScriptManager>
<div>
<telerik:RadDockLayout ID="RadDockLayout1" runat="server"
onsavedocklayout="RadDockLayout1_SaveDockLayout"
onloaddocklayout="RadDockLayout1_LoadDockLayout" EnableEmbeddedSkins="False"
EnableViewState="true" StoreLayoutInViewState="false">
<telerik:RadDockZone ID="RadDockZone1" Runat="server" MinHeight="300px" Width="99%"
style="float:left;" Orientation="Horizontal">
</telerik:RadDockZone>
<div style="display:none">
Hidden UpdatePanel, which is used to receive the new dock controls.
<asp:updatepanel runat="server" id="UpdatePanel1">
</asp:updatepanel>
</div>
</telerik:RadDockLayout>
</div>
<div style="clear:both;"></div>
<div>
<asp:CheckBoxList runat="server" ID="checkboxlist">
<asp:ListItem Value="~/WebUserControl.ascx|300" Enabled="true">Sample1</asp:ListItem>
<asp:ListItem Value="~/WebUserControl.ascx|300" Enabled="true">Sample2</asp:ListItem>
<asp:ListItem Value="~/WebUserControl.ascx|450" Enabled="true">Sample3</asp:ListItem>
</asp:CheckBoxList>
<asp:Button runat="server" ID="Button1" Text="Add Selected" OnClick="AddSelected_Click" />
</div>
</asp:Content>
.CS:
using System;
using System.Collections;
using System.Configuration;
using System.Data;
using System.Web;
using System.Linq;
using System.Web.Security;
using System.Web.UI;
using System.Web.UI.HtmlControls;
using System.Web.UI.WebControls;
using System.Web.UI.WebControls.WebParts;
using System.Web.Script.Serialization;
using System.Collections.Generic;
using System.Text;
using Telerik.Web.UI;
public partial class Default2 : System.Web.UI.Page
{
private const string cookiename = "__example_website";
protected void Page_Load()
{
}
protected void RadDockLayout1_LoadDockLayout(object sender, DockLayoutEventArgs e)
{
HttpCookie positionsCookie = Request.Cookies[cookiename];
if (!Object.Equals(positionsCookie, null))
{
string serializedPositionsAndIndices = positionsCookie.Value;
if (!string.IsNullOrEmpty(serializedPositionsAndIndices))
{
JavaScriptSerializer serializer = new JavaScriptSerializer();
string[] positionsAndIndices = serializer.Deserialize<string[]>(serializedPositionsAndIndices);
e.Positions = serializer.Deserialize<Dictionary<string, string>>(positionsAndIndices[0]);
e.Indices = serializer.Deserialize<Dictionary<string, int>>(positionsAndIndices[1]);
}
}
}
protected void RadDockLayout1_SaveDockLayout(object sender, DockLayoutEventArgs e)
{
JavaScriptSerializer serializer = new JavaScriptSerializer();
string serializedPositions = serializer.Serialize(e.Positions);
string serializedIndices = serializer.Serialize(e.Indices);
HttpCookie positionsCookie = new HttpCookie(cookiename,
serializer.Serialize(new string[] { serializedPositions, serializedIndices }));
//Ensure that the cookie will not expire soon
positionsCookie.Expires = DateTime.Now.AddYears(1);
Response.Cookies.Add(positionsCookie);
}
private RadDock CreateRadDock(string controlpath, string title, int width)
{
RadDock dock = new RadDock();
dock.UniqueName = Guid.NewGuid().ToString();
dock.ID = string.Format("RadDock{0}", dock.UniqueName);
dock.Title = title;
Control control = LoadControl(controlpath);
dock.ContentContainer.Controls.Add(control);
dock.Width = Unit.Pixel(width);
dock.DockMode = DockMode.Docked;
dock.Commands.Add(new DockCloseCommand());
dock.Commands.Add(new DockExpandCollapseCommand());
dock.Command += new DockCommandEventHandler(dock_Command);
return dock;
}
void dock_Command(object sender, DockCommandEventArgs e)
{
if (e.Command.Name == "Close")
{
ScriptManager.RegisterStartupScript(
UpdatePanel1,
this.GetType(),
"RemoveDock",
string.Format(@"function _removeDock() {{
Sys.Application.remove_load(_removeDock);
$find('{0}').undock();
$get('{1}').appendChild($get('{0}'));
$find('{0}').doPostBack('DockPositionChanged');
}};
Sys.Application.add_load(_removeDock);", ((RadDock)sender).ClientID, UpdatePanel1.ClientID),
true);
}
}
private void CreateSaveStateTrigger(RadDock dock)
{
//Ensure that the RadDock control will initiate postback
// when its position changes on the client or any of the commands is clicked.
//Using the trigger we will "ajaxify" that postback.
dock.AutoPostBack = true;
dock.CommandsAutoPostBack = true;
AsyncPostBackTrigger saveStateTrigger = new AsyncPostBackTrigger();
saveStateTrigger.ControlID = dock.ID;
saveStateTrigger.EventName = "DockPositionChanged";
UpdatePanel1.Triggers.Add(saveStateTrigger);
saveStateTrigger = new AsyncPostBackTrigger();
saveStateTrigger.ControlID = dock.ID;
saveStateTrigger.EventName = "Command";
UpdatePanel1.Triggers.Add(saveStateTrigger);
}
protected void AddSelected_Click(Object sender, EventArgs e)
{
List<RadDock> add_docks = new List<RadDock>();
List<RadDock> remove_docks = new List<RadDock>();
foreach (ListItem li in checkboxlist.Items)
{
bool exists = RadDockZone1.Docks.Where(d => d.Title == li.Text).Count() > 0;
if (li.Selected)
{
if (!exists)
{
string[] values = li.Value.Split('|');
RadDock dock = CreateRadDock(values[0], li.Text, Int32.Parse(values[1]));
UpdatePanel1.ContentTemplateContainer.Controls.Add(dock);
add_docks.Add(dock);
CreateSaveStateTrigger(dock);
}
}
else
{
if (exists)
{
RadDock dock = RadDockZone1.Docks.FirstOrDefault(cds => cds.Title == li.Text);
remove_docks.Add(dock);
}
}
}
if (add_docks.Count > 0)
{
StringBuilder script = new StringBuilder();
script.Append(@"function _addDock() {{");
script.AppendLine();
script.Append(@"Sys.Application.remove_load(_addDock); ");
script.AppendLine();
foreach (RadDock d in add_docks)
{
script.AppendFormat(@"$find('{0}').dock($find('{1}'));", RadDockZone1.ClientID, d.ClientID);
script.AppendLine();
}
script.AppendFormat(@"$find('{0}').doPostBack('DockPositionChanged');", add_docks[0].ClientID);
script.AppendLine();
script.Append(@"}};");
script.AppendLine();
script.Append(@"Sys.Application.add_load(_addDock);");
script.AppendLine();
ScriptManager.RegisterStartupScript(
this,
this.GetType(),
"AddDocks",
script.ToString(),
true);
}
if (remove_docks.Count > 0)
{
StringBuilder r_script = new StringBuilder();
r_script.AppendLine(@"function _removeDock() {{");
r_script.AppendLine("Sys.Application.remove_load(_removeDock);");
foreach (RadDock d in remove_docks)
{
r_script.AppendFormat(@"$find('{0}').undock();", d.ClientID);
r_script.AppendLine();
r_script.AppendFormat(@"$get('{1}').appendChild($get('{0}'));", d.ClientID, UpdatePanel1.ClientID);
r_script.AppendLine();
// Close the raddock - to hide it in the updatepanel
d.Closed = true;
}
r_script.AppendFormat(@"$find('{0}').doPostBack('DockPositionChanged');", remove_docks[0].ClientID);
r_script.AppendLine();
r_script.AppendLine(@"}};");
r_script.AppendLine(@"Sys.Application.add_load(_removeDock);");
ScriptManager.RegisterStartupScript(
this,
this.GetType(),
"RemoveDocks",
r_script.ToString(),
true);
}
}
}
I'm messing around with creating a dock page which has several selectable controls which you can add to a single dock. I got this working fine with session objects, but am struggling trying to move it to use cookies. Could you help?
The problem seems to be that it looses the controls from the dock after the postback. In the example I was using with sessions, there was some code in the page_load which recreated the docks, I'm not really sure how to do this from the information that is stored in the cookie. Should I be looking at serializing the dockstate dictionary, or recreating the docks from the cookie information? Heres the code I've got:
Thanks for any suggestions,
Lee.
It also uses a master page and a web user control, but these have nothing in them except some html to test with.
ASPX:
<%@ Page Language="C#" MasterPageFile="~/MasterPage.master" AutoEventWireup="true" CodeFile="Default2.aspx.cs" Inherits="Default2" Title="Untitled Page" %>
<%@ Register src="WebUserControl.ascx" tagname="SampleWidget" tagprefix="uc1" %>
<%@ Register assembly="Telerik.Web.UI" namespace="Telerik.Web.UI" tagprefix="telerik" %>
<asp:Content ID="Content1" ContentPlaceHolderID="head" Runat="Server">
</asp:Content>
<asp:Content ID="Content2" ContentPlaceHolderID="ContentPlaceHolder1" Runat="Server">
<asp:ScriptManager ID="ScriptManager1" runat="server">
</asp:ScriptManager>
<div>
<telerik:RadDockLayout ID="RadDockLayout1" runat="server"
onsavedocklayout="RadDockLayout1_SaveDockLayout"
onloaddocklayout="RadDockLayout1_LoadDockLayout" EnableEmbeddedSkins="False"
EnableViewState="true" StoreLayoutInViewState="false">
<telerik:RadDockZone ID="RadDockZone1" Runat="server" MinHeight="300px" Width="99%"
style="float:left;" Orientation="Horizontal">
</telerik:RadDockZone>
<div style="display:none">
Hidden UpdatePanel, which is used to receive the new dock controls.
<asp:updatepanel runat="server" id="UpdatePanel1">
</asp:updatepanel>
</div>
</telerik:RadDockLayout>
</div>
<div style="clear:both;"></div>
<div>
<asp:CheckBoxList runat="server" ID="checkboxlist">
<asp:ListItem Value="~/WebUserControl.ascx|300" Enabled="true">Sample1</asp:ListItem>
<asp:ListItem Value="~/WebUserControl.ascx|300" Enabled="true">Sample2</asp:ListItem>
<asp:ListItem Value="~/WebUserControl.ascx|450" Enabled="true">Sample3</asp:ListItem>
</asp:CheckBoxList>
<asp:Button runat="server" ID="Button1" Text="Add Selected" OnClick="AddSelected_Click" />
</div>
</asp:Content>
.CS:
using System;
using System.Collections;
using System.Configuration;
using System.Data;
using System.Web;
using System.Linq;
using System.Web.Security;
using System.Web.UI;
using System.Web.UI.HtmlControls;
using System.Web.UI.WebControls;
using System.Web.UI.WebControls.WebParts;
using System.Web.Script.Serialization;
using System.Collections.Generic;
using System.Text;
using Telerik.Web.UI;
public partial class Default2 : System.Web.UI.Page
{
private const string cookiename = "__example_website";
protected void Page_Load()
{
}
protected void RadDockLayout1_LoadDockLayout(object sender, DockLayoutEventArgs e)
{
HttpCookie positionsCookie = Request.Cookies[cookiename];
if (!Object.Equals(positionsCookie, null))
{
string serializedPositionsAndIndices = positionsCookie.Value;
if (!string.IsNullOrEmpty(serializedPositionsAndIndices))
{
JavaScriptSerializer serializer = new JavaScriptSerializer();
string[] positionsAndIndices = serializer.Deserialize<string[]>(serializedPositionsAndIndices);
e.Positions = serializer.Deserialize<Dictionary<string, string>>(positionsAndIndices[0]);
e.Indices = serializer.Deserialize<Dictionary<string, int>>(positionsAndIndices[1]);
}
}
}
protected void RadDockLayout1_SaveDockLayout(object sender, DockLayoutEventArgs e)
{
JavaScriptSerializer serializer = new JavaScriptSerializer();
string serializedPositions = serializer.Serialize(e.Positions);
string serializedIndices = serializer.Serialize(e.Indices);
HttpCookie positionsCookie = new HttpCookie(cookiename,
serializer.Serialize(new string[] { serializedPositions, serializedIndices }));
//Ensure that the cookie will not expire soon
positionsCookie.Expires = DateTime.Now.AddYears(1);
Response.Cookies.Add(positionsCookie);
}
private RadDock CreateRadDock(string controlpath, string title, int width)
{
RadDock dock = new RadDock();
dock.UniqueName = Guid.NewGuid().ToString();
dock.ID = string.Format("RadDock{0}", dock.UniqueName);
dock.Title = title;
Control control = LoadControl(controlpath);
dock.ContentContainer.Controls.Add(control);
dock.Width = Unit.Pixel(width);
dock.DockMode = DockMode.Docked;
dock.Commands.Add(new DockCloseCommand());
dock.Commands.Add(new DockExpandCollapseCommand());
dock.Command += new DockCommandEventHandler(dock_Command);
return dock;
}
void dock_Command(object sender, DockCommandEventArgs e)
{
if (e.Command.Name == "Close")
{
ScriptManager.RegisterStartupScript(
UpdatePanel1,
this.GetType(),
"RemoveDock",
string.Format(@"function _removeDock() {{
Sys.Application.remove_load(_removeDock);
$find('{0}').undock();
$get('{1}').appendChild($get('{0}'));
$find('{0}').doPostBack('DockPositionChanged');
}};
Sys.Application.add_load(_removeDock);", ((RadDock)sender).ClientID, UpdatePanel1.ClientID),
true);
}
}
private void CreateSaveStateTrigger(RadDock dock)
{
//Ensure that the RadDock control will initiate postback
// when its position changes on the client or any of the commands is clicked.
//Using the trigger we will "ajaxify" that postback.
dock.AutoPostBack = true;
dock.CommandsAutoPostBack = true;
AsyncPostBackTrigger saveStateTrigger = new AsyncPostBackTrigger();
saveStateTrigger.ControlID = dock.ID;
saveStateTrigger.EventName = "DockPositionChanged";
UpdatePanel1.Triggers.Add(saveStateTrigger);
saveStateTrigger = new AsyncPostBackTrigger();
saveStateTrigger.ControlID = dock.ID;
saveStateTrigger.EventName = "Command";
UpdatePanel1.Triggers.Add(saveStateTrigger);
}
protected void AddSelected_Click(Object sender, EventArgs e)
{
List<RadDock> add_docks = new List<RadDock>();
List<RadDock> remove_docks = new List<RadDock>();
foreach (ListItem li in checkboxlist.Items)
{
bool exists = RadDockZone1.Docks.Where(d => d.Title == li.Text).Count() > 0;
if (li.Selected)
{
if (!exists)
{
string[] values = li.Value.Split('|');
RadDock dock = CreateRadDock(values[0], li.Text, Int32.Parse(values[1]));
UpdatePanel1.ContentTemplateContainer.Controls.Add(dock);
add_docks.Add(dock);
CreateSaveStateTrigger(dock);
}
}
else
{
if (exists)
{
RadDock dock = RadDockZone1.Docks.FirstOrDefault(cds => cds.Title == li.Text);
remove_docks.Add(dock);
}
}
}
if (add_docks.Count > 0)
{
StringBuilder script = new StringBuilder();
script.Append(@"function _addDock() {{");
script.AppendLine();
script.Append(@"Sys.Application.remove_load(_addDock); ");
script.AppendLine();
foreach (RadDock d in add_docks)
{
script.AppendFormat(@"$find('{0}').dock($find('{1}'));", RadDockZone1.ClientID, d.ClientID);
script.AppendLine();
}
script.AppendFormat(@"$find('{0}').doPostBack('DockPositionChanged');", add_docks[0].ClientID);
script.AppendLine();
script.Append(@"}};");
script.AppendLine();
script.Append(@"Sys.Application.add_load(_addDock);");
script.AppendLine();
ScriptManager.RegisterStartupScript(
this,
this.GetType(),
"AddDocks",
script.ToString(),
true);
}
if (remove_docks.Count > 0)
{
StringBuilder r_script = new StringBuilder();
r_script.AppendLine(@"function _removeDock() {{");
r_script.AppendLine("Sys.Application.remove_load(_removeDock);");
foreach (RadDock d in remove_docks)
{
r_script.AppendFormat(@"$find('{0}').undock();", d.ClientID);
r_script.AppendLine();
r_script.AppendFormat(@"$get('{1}').appendChild($get('{0}'));", d.ClientID, UpdatePanel1.ClientID);
r_script.AppendLine();
// Close the raddock - to hide it in the updatepanel
d.Closed = true;
}
r_script.AppendFormat(@"$find('{0}').doPostBack('DockPositionChanged');", remove_docks[0].ClientID);
r_script.AppendLine();
r_script.AppendLine(@"}};");
r_script.AppendLine(@"Sys.Application.add_load(_removeDock);");
ScriptManager.RegisterStartupScript(
this,
this.GetType(),
"RemoveDocks",
r_script.ToString(),
true);
}
}
}