I'm trying to create a "Widget Portal" for an existing website.
I've used the example and customized it a bit which has lead to the following result:
<%@ Register TagPrefix="telerik" Namespace="Telerik.Web.UI" Assembly="Telerik.Web.UI" %> |
<asp:UpdatePanel runat="server" ID="UpdatePanel2"> |
<ContentTemplate> |
<telerik:RadDockLayout runat="server" ID="RadDockLayout1" EnableEmbeddedSkins="false" Skin="Telerik" |
OnSaveDockLayout="RadDockLayout1_SaveDockLayout" OnLoadDockLayout="RadDockLayout1_LoadDockLayout"> |
<table cellspacing="5" cellpadding="5" width="100%"> |
<tr> |
<td style="width: 50%;"> |
<telerik:RadDockZone runat="server" ID="Column1" Orientation="vertical" FitDocks="true" EnableEmbeddedScripts="true" |
Style="border: 0px;width: 99%;" Skin="Telerik" > |
</telerik:RadDockZone> |
</td> |
<td style="width: 50%;"> |
<telerik:RadDockZone runat="server" ID="Column2" Orientation="vertical" FitDocks="true" EnableEmbeddedScripts="true" |
Style="border: 0px;width: 99%;" Skin="Telerik"> |
</telerik:RadDockZone> |
</td> |
</tr> |
</table> |
</telerik:RadDockLayout> |
</ContentTemplate> |
<Triggers> |
<asp:AsyncPostBackTrigger ControlID="ButtonAddDock" EventName="Click" /> |
</Triggers> |
</asp:UpdatePanel> |
<div style="width: 0px; height: 0px; overflow: hidden; position: absolute; left: -10000px;"> |
Hidden UpdatePanel, which is used to help with saving state when minimizing, moving |
and closing docks. This way the docks state is saved faster (no need to update the |
docking zones). |
<asp:UpdatePanel runat="server" ID="UpdatePanel1"> |
</asp:UpdatePanel> |
</div> |
<asp:Button runat="server" ID="ButtonAddDock" Text="Widget Toevoegen" OnClick="ButtonAddDock_Click" /> |
<asp:DropDownList ID="DropDownWidget" runat="server" DataSourceID="widgetDataSource" DataTextField="Name" DataValueField="ID"/> |
<asp:DropDownList ID="DropDownColumn" runat="server" DataSource="<%#GetZones() %>" DataTextField="ID" DataValueField="ClientID"/> |
public partial class WidgetPortal : System.Web.UI.UserControl |
{ |
WidgetFrameworkHandler wfh = new WidgetFrameworkHandler(); |
private List<DockState> CurrentDockStates |
{ |
get |
{ |
//Store the info about the added docks in the session. For real life |
// applications we recommend using database or other storage medium |
// for persisting this information. |
List<DockState> _currentDockStates = (List<DockState>)Session["CurrentDockStatesDynamicDocks"]; |
if (Object.Equals(_currentDockStates, null)) |
{ |
// _currentDockStates = CreateDockState(); |
_currentDockStates = new List<DockState>(); |
Session["CurrentDockStatesDynamicDocks"] = _currentDockStates; |
} |
return _currentDockStates; |
} |
set |
{ |
Session["CurrentDockStatesDynamicDocks"] = value; |
} |
} |
private List<DockState> CreateDockState() |
{ |
List<DockState> returnList = new List<DockState>(); |
List<PORT_Widget_Instance> widgets = wfh.LoadWidgets(); |
foreach (PORT_Widget_Instance widget in widgets) |
{ |
DockState ds = new DockState(); |
ds.Collapsed = widget.Expanded; |
ds.DockZoneID = "Column" +widget.Column_; |
ds.Title = widget.Title; |
returnList.Add(ds); |
} |
return returnList; |
} |
private RadDock CreateRadDockFromState(DockState state) |
{ |
RadDock dock = new RadDock(); |
dock.DockMode = DockMode.Docked; |
dock.ID = string.Format("RadDock{0}", state.UniqueName); |
dock.ApplyState(state); // <-- Deze verneukt het.. is state niet gezet ? |
dock.Commands.Add(new DockCloseCommand()); |
dock.Commands.Add(new DockExpandCollapseCommand()); |
return dock; |
} |
private RadDock CreateRadDock() |
{ |
int docksCount = CurrentDockStates.Count; |
RadDock dock = new RadDock(); |
dock.DockMode = DockMode.Docked; |
dock.UniqueName = Guid.NewGuid().ToString(); |
dock.ID = string.Format("RadDock{0}", dock.UniqueName); |
dock.Title = "Dock"; |
dock.Text = string.Format("Added at {0}", DateTime.Now); |
dock.Commands.Add(new DockCloseCommand()); |
dock.Commands.Add(new DockExpandCollapseCommand()); |
return dock; |
} |
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; |
dock.AutoPostBack = true; |
AsyncPostBackTrigger saveStateTrigger = new AsyncPostBackTrigger(); |
saveStateTrigger.ControlID = dock.ID; |
saveStateTrigger.EventName = "Command"; |
UpdatePanel1.Triggers.Add(saveStateTrigger); |
saveStateTrigger = new AsyncPostBackTrigger(); |
saveStateTrigger.ControlID = dock.ID; |
saveStateTrigger.EventName = "DockPositionChanged"; |
UpdatePanel1.Triggers.Add(saveStateTrigger); |
} |
protected void Page_Init(object sender, EventArgs e) |
{ |
//Recreate the docks in order to ensure their proper operation |
for (int i = 0; i < CurrentDockStates.Count; i++) |
{ |
RadDock dock = CreateRadDockFromState(CurrentDockStates[i]); |
//We will just add the RadDock control to the RadDockLayout. |
// You could use any other control for that purpose, just ensure |
// that it is inside the RadDockLayout control. |
// The RadDockLayout control will automatically move the RadDock |
// controls to their corresponding zone in the LoadDockLayout |
// event (see below). |
RadDockLayout1.Controls.Add(dock); |
//We want to save the dock state every time a dock is moved. |
CreateSaveStateTrigger(dock); |
LoadWidget(dock); |
} |
} |
protected void RadDockLayout1_LoadDockLayout(object sender, DockLayoutEventArgs e) |
{ |
//Populate the event args with the state information. The RadDockLayout control |
// will automatically move the docks according that information. |
foreach (DockState state in CurrentDockStates) |
{ |
e.Positions[state.UniqueName] = state.DockZoneID; |
e.Indices[state.UniqueName] = state.Index; |
} |
} |
protected void RadDockLayout1_SaveDockLayout(object sender, DockLayoutEventArgs e) |
{ |
//Save the dock state in the page Session. This will enable us |
// to recreate the dock in the next Page_Init. |
CurrentDockStates = RadDockLayout1.GetRegisteredDocksState(); |
} |
protected void ButtonAddDock_Click(object sender, EventArgs e) |
{ |
RadDock dock = CreateRadDock(); |
RadDockZone dz = (RadDockZone)FindControl(DropDownColumn.SelectedItem.Text); |
dz.Controls.Add(dock); |
CreateSaveStateTrigger(dock); |
dock.Tag = DropDownWidget.SelectedValue; |
LoadWidget(dock); |
} |
private void LoadWidget(RadDock dock) |
{ |
if (string.IsNullOrEmpty(dock.Tag)) |
{ |
return; |
} |
int widgetID = Convert.ToInt32(dock.Tag); |
PORT_Widgets wdg = wfh.GetWidget(widgetID); |
Control widget = LoadControl("Widgets/" + wdg.Url); |
dock.ContentContainer.Controls.Add(widget); |
} |
public ArrayList GetZones() |
{ |
ArrayList zones = new ArrayList(); |
zones.Add(Column1); |
zones.Add(Column2); |
return zones; |
} |
protected void Page_Load(object sender, EventArgs e) |
{ |
if (!IsPostBack) |
{ |
DropDownColumn.DataBind(); |
} |
} |
} |
When I add the widgets (with UserControls inside them) it works fine. It also stores it's state.
However when I drag a widget and drop it in a different RadDockZone or within a different place within the same
RadDockZone the state isn't saved and the state that was saved before (the one that was saved when I added a new widget) is reloaded. I think it has something to do with the lifecycle or the time when the layout is supposed to be saved.
So in summary: my problem is the state will not be saved when I drag/drop my widgets this way.. I don't know why.
Could someone please tell me what I'm doing wrong ?