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

Save/Load docklayout

9 Answers 435 Views
Dock
This is a migrated thread and some comments may be shown as answers.
Sentia
Top achievements
Rank 1
Sentia asked on 05 Aug 2007, 10:32 PM
Hi,

Im building a portal website, but not creating docks dynamically.

Im attempting to persist dock state information to a cookie using the demo. I've basically copied your code but it doesnt seem to be fired the events as I'd expected.

I would imagine that SaveDockLayout be fired just prior to browsing off the page, and LoadDockLayout be fired when browing to the page, however, SaveDock layout doesnt when exiting the page.

Could you please shed some light on this situation?

9 Answers, 1 is accepted

Sort by
0
Petya
Telerik team
answered on 06 Aug 2007, 11:01 AM
Hello team@sentia.com.au,

Here is the control life cycle in the page life cycle:

Page.PreInit
Controls.Init
Page.Init
Page.TrackViewState
Controls.TrackViewState
Page.InitComplete
    RadDockLayout.LoadDockLayout
if (IsPostBack)
{
  Page.LoadViewState                 
  Controls.LoadViewState
}
Controls.LoadPostData
    RadDock.DockPositionChanged
Page.PreLoad                             
Page.Load
Controls.Load
Controls.DataChangedEvents (such as TextBox.TextChanged)
Controls.PostBackEvents (such as Button.Click)
    RadDock.OnCommand
Page.LoadComplete
Page.PreRender
Controls.PreRender
Page.PreRenderComplete
Controls.SaveViewState           
Page.SaveViewState
Page.SaveStateComplete
    RadDockLayout.SaveDockLayout
Render

As you can see SaveDockLayout is raised at a late stage of the page life cycle and later that a button click. Therefore, if you browse off the page with Response.Redirect in a button click, the redirect takes place in the button click and SaveDockLayout is never reached.

Regards,
Petya
the Telerik team

Instantly find answers to your questions at the new Telerik Support Center
0
Lal
Top achievements
Rank 1
answered on 08 Apr 2008, 12:26 AM
Hi,
I am able to save the current state in database. (I am getting the current state using  this.RadDockLayout1.GetRegisteredDocksState().  How do I restore it back? The javascript serialize doesn't work very well. Is there anything like the " RadDockingManager1.LoadState( string previousState );" that was there earlier?
0
Obi-Wan Kenobi
Top achievements
Rank 1
answered on 10 Apr 2008, 11:23 AM
RadDock doesn't have Save and LoadState methods.
You can find an online example, where the state is saved and loaded with javascriptserlializer in cookie here:
http://www.telerik.com/DEMOS/ASPNET/Prometheus/Dock/Examples/LoadSaveLayout/DefaultCS.aspx
0
Nicolas
Top achievements
Rank 1
answered on 21 May 2008, 05:51 PM
That example doesn't make sense to me. Why would I want to save the state before the user has a chance to modify the layout.  I put a breakpoint on the savelayout event and it never fired when the page was "unloaded".  For example it would be nice to save the layout when the user navigates away from the page with my docklayout control and only load when they enter the page with the docklayout control. Ultimately, my goal is to save the state in a database and load it from there.  This was very easy with the last version of the controls that I worked with.  They had SaveLayout and LoadLayout functions which simply handled a string and I could execute that whenever I wanted.  Now I depend on these event arguments in order to alter the state of the docklayout.  Is there a better way?
0
Nicolas
Top achievements
Rank 1
answered on 21 May 2008, 05:51 PM

Editted double post, sorry.

0
Sophy
Telerik team
answered on 22 May 2008, 10:41 AM
Hi Nicolas,

As it is described in one of the previous posts the SaveDockLayout is executed after any Controls.DataChangedEvents and Controls.PostBackEvents as well as after DockPositionChanged and dock's Command events but before the Page Unload event. In this way users' interactions are saved in the state. However, changing dock's position and any command click should do a postback or a callback in order to notify the server about the user's action. An example demonstrating how docks' states are saved and loaded when navigating to other pages you can find in the Dynamically Created Docks online example.

If you want to save the positions of the docks whenever you want (upon a button click event for example) instead of at savedocklayout you simply need to store the info about the added docks in session/cookie/database when the button is clicked. You need to simply move the code from the savedocklayout event handler to your button's event handler. For your convenience I have prepared an example demonstrating how to save the dock's state at a button click. There are some comments which can help you better understand the provided implementation. You will need to modify it so that it is answers the requirements of your scenario. Please, review the attached example and let me know if you need further assistance.


Best regards,

Sophy
the Telerik team


Instantly find answers to your questions at the new Telerik Support Center
0
John
Top achievements
Rank 1
answered on 22 May 2008, 11:26 AM
Sorry, I posted to wrong post.

John
0
Michael Harrison
Top achievements
Rank 1
answered on 03 Jan 2009, 11:45 AM
Hi Sophy,
  The example looks good however there is one snag with serialisation in general: the Unit object cannot be serialised.  This means that once the object has been serialised then deserialised then properties such as Top, Left, Width and Height all loose their values.  This has nothing to do with Telerik components but with the .NET Framework and missing serialisation.  it will however directly effect the examples created by Telerik for Load / Save.

I had a look into a work around and there are a couple of options: use XML Serialisation or Create a class that inherits DockState and provides a work around for the effected properties.  So far I have implemented the XML Serialisation where after serialisation I set the properties:

using System; 
using System.Collections; 
using System.Collections.Generic; 
using System.ComponentModel; 
using System.Data; 
using System.IO; 
using System.Web; 
using System.Web.Script.Serialization; 
using System.Web.SessionState; 
using System.Web.UI; 
using System.Web.UI.WebControls; 
using System.Web.UI.HtmlControls; 
using System.Xml; 
using System.Xml.Serialization; 
 
using Telerik.Web.UI; 
 
namespace Telerik.Web.Examples.Dock.LoadSaveExample 
    public partial class DefaultCS : Page 
    { 
        ArrayList DockStates  
        { 
            get  
            {  
                if (Session["AutoPostBack_DockStatesString"] == null)  
                    Session["AutoPostBack_DockStatesString"] = new ArrayList(); 
 
                return ((ArrayList)Session["AutoPostBack_DockStatesString"]);  
            } 
            set 
            { 
                Session["AutoPostBack_DockStatesString"] = value; 
            } 
        } 
 
        private void Page_Load(object sender, EventArgs e) 
        { 
            if (!Page.IsPostBack) 
            { 
            } 
        } 
 
        protected void btnLoad_Click(object sender, EventArgs e) 
        { 
            LoadDockState(); 
        } 
 
        protected void btnSave_Click(object sender, EventArgs e) 
        { 
            SaveDockState(RadDockLayout1.GetRegisteredDocksState()); 
        } 
 
        protected void Page_Init(object sender, EventArgs e) 
        { 
            BuildThePage(); 
        } 
 
        private void SaveDockState(List<DockState> dockStates) 
        { 
            XmlSerializer serializer = new XmlSerializer(typeof(DockState)); 
            TextWriter writer = null
            XmlDocument doc = null
            DockStates.Clear(); 
            foreach (DockState state in dockStates) 
            { 
                writer = new StringWriter(); 
                serializer.Serialize(writer, state); 
                doc = new XmlDocument(); 
                doc.LoadXml(((StringWriter)writer).ToString()); 
                doc["DockState"]["Top"].InnerText = state.Top.ToString(); 
                doc["DockState"]["Left"].InnerText = state.Left.ToString(); 
                doc["DockState"]["Width"].InnerText = state.Width.ToString(); 
                doc["DockState"]["Height"].InnerText = state.Height.ToString(); 
                DockStates.Add(doc.InnerXml); 
            } 
        } 
 
        private void LoadDockState() 
        { 
            if (DockStates != null
            { 
                XmlSerializer serializer = new XmlSerializer(typeof(DockState)); 
                DockState state = null
                RadDock dock = null
                XmlDocument doc; 
                TextReader reader; 
                string top, left, width, height; 
 
 
                foreach (string stateString in DockStates) 
                { 
                    doc = new XmlDocument(); 
                    doc.Load(new StringReader(stateString)); 
                    top = doc["DockState"]["Top"].InnerText; 
                    doc["DockState"]["Top"].InnerText = string.Empty; 
                    left = doc["DockState"]["Left"].InnerText; 
                    doc["DockState"]["Left"].InnerText = string.Empty; 
                    height = doc["DockState"]["Height"].InnerText; 
                    doc["DockState"]["Height"].InnerText = string.Empty; 
                    width = doc["DockState"]["Width"].InnerText; 
                    doc["DockState"]["Width"].InnerText = string.Empty; 
 
                    reader = new StringReader(doc.InnerXml); 
                    state = (DockState)serializer.Deserialize(reader); 
                    state.Top = new Unit(top); 
                    state.Left = new Unit(left); 
                    state.Width = new Unit(width); 
                    state.Height = new Unit(height); 
                    dock = (RadDock)RadDockLayout1.FindControl(state.UniqueName); 
                    dock.ApplyState(state); 
                } 
            } 
        } 
 
        private void BuildThePage() 
        { 
            for (int i = 1; i <= 5; i++) 
            { 
                RadDock rd = new RadDock(); 
                rd.ID = "DockPhoto_" + i.ToString(); 
                rd.Title = "dock" + i.ToString(); 
                rd.Text = "de, ferment purus, fauctus fring dui. Pellus ut ferment mi, imperdum in non dignisl. Nunc. Vivamus nu. Pellentum nonummy sed tor sit ametus sit amet liberos pretium viverra, posuere venean nunc odio eumst. Vivamus estibulum at, rhoncus, potentum. Cras torta nec elementum. Proin viverra arcu. Etiam.Cum antes, justo. In malestibus, placilis tortis, feugiat. Nunc iacus. Maecenas et loreet posuere odMorbi ipsum vestas mus. Proin dapien ipsum sempus orna elitortis, mauris mi. Mauris nunc vitae, tem"
                rd.Width = Unit.Pixel(120); 
                rd.Height = Unit.Pixel(120); 
                rd.EnableViewState = false
                rd.DockMode = DockMode.Default; 
                RadDockZone1.Controls.Add(rd); 
            } 
        } 
    } 

<%@ page language="c#" autoeventwireup="true" inherits="Telerik.Web.Examples.Dock.LoadSaveExample.DefaultCS" 
    codefile="DefaultCS.aspx.cs" %> 
 
<%@ register tagprefix="telerik" namespace="Telerik.Web.UI" assembly="Telerik.Web.UI" %> 
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/tr/xhtml11/dtd/xhtml11.dtd"> 
<html xmlns="http://www.w3.org/1999/xhtml"
<head runat="server"
    <!--[if lte IE 6]> 
    <style type="text/css"
    .raddockzone{height:250px} 
    </style> 
    <![endif]--> 
</head> 
<body class="BODY"
    <form id="Form1" method="post" runat="server"
        <telerik:RadScriptManager ID="rsmGeneral" runat="server" /> 
        <telerik:RadAjaxManager  
            ID="ramGeneral" 
            runat="server" 
            > 
            <AjaxSettings> 
                <telerik:AjaxSetting AjaxControlID="btnSave" EventName="Click"
                    <UpdatedControls> 
                        <telerik:AjaxUpdatedControl ControlID="RadDockZone1" LoadingPanelID="" /> 
                        <telerik:AjaxUpdatedControl ControlID="RadDockZone2" LoadingPanelID="" /> 
                    </UpdatedControls> 
                </telerik:AjaxSetting> 
                <telerik:AjaxSetting AjaxControlID="btnLoad" EventName="Click"
                    <UpdatedControls> 
                        <telerik:AjaxUpdatedControl ControlID="RadDockZone1" LoadingPanelID="" /> 
                        <telerik:AjaxUpdatedControl ControlID="RadDockZone2" LoadingPanelID="" /> 
                    </UpdatedControls> 
                </telerik:AjaxSetting> 
            </AjaxSettings> 
        </telerik:RadAjaxManager> 
        <asp:Button ID="btnSave" Text="Save" OnClick="btnSave_Click" runat="server" /> 
        <asp:Button ID="btnLoad" Text="Load" OnClick="btnLoad_Click" runat="server" /> 
        <telerik:raddocklayout runat="server" id="RadDockLayout1"
            <table> 
                <tr> 
                    <td valign="top"
                        Docking Zone 1 
                        <telerik:raddockzone runat="server" id="RadDockZone1" width="330" minheight="250"
                        </telerik:raddockzone> 
                    </td> 
                    <td valign="top"
                        Docking Zone 2 
                        <telerik:raddockzone runat="server" id="RadDockZone2" width="310" minheight="250"
                        </telerik:raddockzone> 
                    </td> 
                </tr> 
            </table> 
        </telerik:raddocklayout> 
    </form> 
</body> 
</html> 
 

This is not ideal so I'm looking into the second option.  That said this does work however not for floating docks.  They simply disappear.  I don't think that the second option will work.  Any suggestions?

Until I resolve the floating docks I'm going to disable the option for floating docks (ie myDock.DockMode = DockMode.Docked)
Thanks in advance.
Cheers,

Michael




0
Nikolay Raykov
Telerik team
answered on 05 Jan 2009, 12:47 PM
Hello Michael,

Indeed, this problem exists when serializing/deserializing the state of the docks.

I can suggest a more generic approach to solve this problem. You could write your own custom JavaScriptConverter class which will take care of serialization and deserialization processes. In order this class to be used you need to register it into the JavaScriptSerializer object using the code below:

System.Web.Script.Serialization.JavaScriptSerializer serializer = new System.Web.Script.Serialization.JavaScriptSerializer();  
List<System.Web.Script.Serialization.JavaScriptConverter> converters = new List<System.Web.Script.Serialization.JavaScriptConverter>();  
converters.Add(new UnitConverter());  
serializer.RegisterConverters(converters); 

Now you will be able to persist the position of the docks (even the ones that are floated).

Please find the attached JavaScriptConverter class which takes care of serialization of the Unit structure and your code-behind file for the aspx page.

Best wishes,
Nikolay Raykov
the Telerik team

Check out Telerik Trainer, the state of the art learning tool for Telerik products.
Tags
Dock
Asked by
Sentia
Top achievements
Rank 1
Answers by
Petya
Telerik team
Lal
Top achievements
Rank 1
Obi-Wan Kenobi
Top achievements
Rank 1
Nicolas
Top achievements
Rank 1
Sophy
Telerik team
John
Top achievements
Rank 1
Michael Harrison
Top achievements
Rank 1
Nikolay Raykov
Telerik team
Share this question
or