This is a migrated thread and some comments may be shown as answers.

Saving Dock's positions when moved

3 Answers 139 Views
Dock
This is a migrated thread and some comments may be shown as answers.
Jeroen
Top achievements
Rank 2
Jeroen asked on 11 Jun 2009, 11:14 AM
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 ?

3 Answers, 1 is accepted

Sort by
0
Jeroen
Top achievements
Rank 2
answered on 12 Jun 2009, 07:29 AM
I wasn't completely clear before.
The RadDockLayout1_SaveDockLayout is fired but with the wrong positions.
I think this is because the PageInit is fired first and this reloads the positions in which they were saved BEFORE.
Only after that the RadDockLayout1_SaveDockLayout is fired.
0
Accepted
Obi-Wan Kenobi
Top achievements
Rank 1
answered on 17 Jun 2009, 11:43 AM
I think that this problem appears if the UserControl is not added in Page_Init, so you should add the UserControl in Page_Init
0
Jeroen
Top achievements
Rank 2
answered on 17 Jun 2009, 01:53 PM
Thanks, that did it!
Tags
Dock
Asked by
Jeroen
Top achievements
Rank 2
Answers by
Jeroen
Top achievements
Rank 2
Obi-Wan Kenobi
Top achievements
Rank 1
Share this question
or