Saving Dock's positions when moved

4 posts, 1 answers
  1. Jeroen
    Jeroen avatar
    9 posts
    Member since:
    Feb 2006

    Posted 11 Jun 2009 Link to this post

    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 ?
  2. Jeroen
    Jeroen avatar
    9 posts
    Member since:
    Feb 2006

    Posted 12 Jun 2009 Link to this post

    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.
  3. Answer
    Obi-Wan Kenobi
    Obi-Wan Kenobi  avatar
    460 posts
    Member since:
    Aug 2007

    Posted 17 Jun 2009 Link to this post

    I think that this problem appears if the UserControl is not added in Page_Init, so you should add the UserControl in Page_Init
  4. Jeroen
    Jeroen avatar
    9 posts
    Member since:
    Feb 2006

    Posted 17 Jun 2009 Link to this post

    Thanks, that did it!
Back to Top