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 ?