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

Dynamic controls and cookies.

6 Answers 150 Views
Dock
This is a migrated thread and some comments may be shown as answers.
Developer
Top achievements
Rank 1
Developer asked on 13 May 2008, 02:14 PM
Hi,

I'm messing around with creating a dock page which has several selectable controls which you can add to a single dock. I got this working fine with session objects, but am struggling trying to move it to use cookies. Could you help?

The problem seems to be that it looses the controls from the dock after the postback. In the example I was using with sessions, there was some code in the page_load which recreated the docks, I'm not really sure how to do this from the information that is stored in the cookie. Should I be looking at serializing the dockstate dictionary, or recreating the docks from the cookie information? Heres the code I've got:

Thanks for any suggestions,
Lee.

It also uses a master page and a web user control, but these have nothing in them except some html to test with.

ASPX:

<%@ Page Language="C#" MasterPageFile="~/MasterPage.master" AutoEventWireup="true" CodeFile="Default2.aspx.cs" Inherits="Default2" Title="Untitled Page" %>

<%@ Register src="WebUserControl.ascx" tagname="SampleWidget" tagprefix="uc1" %>

<%@ Register assembly="Telerik.Web.UI" namespace="Telerik.Web.UI" tagprefix="telerik" %>

<asp:Content ID="Content1" ContentPlaceHolderID="head" Runat="Server">
</asp:Content>

<asp:Content ID="Content2" ContentPlaceHolderID="ContentPlaceHolder1" Runat="Server">

    <asp:ScriptManager ID="ScriptManager1" runat="server">
    </asp:ScriptManager>

    <div>
        <telerik:RadDockLayout ID="RadDockLayout1" runat="server"
            onsavedocklayout="RadDockLayout1_SaveDockLayout"
            onloaddocklayout="RadDockLayout1_LoadDockLayout" EnableEmbeddedSkins="False"
            EnableViewState="true" StoreLayoutInViewState="false">
               
           
            <telerik:RadDockZone ID="RadDockZone1" Runat="server" MinHeight="300px" Width="99%"
            style="float:left;" Orientation="Horizontal">
           
           
            </telerik:RadDockZone>
           
            <div style="display:none">
                Hidden UpdatePanel, which is used to receive the new dock controls.
                <asp:updatepanel runat="server" id="UpdatePanel1">
                </asp:updatepanel>
            </div>
           
        </telerik:RadDockLayout>
    </div>

    <div style="clear:both;"></div>
   
    <div>
       
        <asp:CheckBoxList runat="server" ID="checkboxlist">
            <asp:ListItem Value="~/WebUserControl.ascx|300" Enabled="true">Sample1</asp:ListItem>
            <asp:ListItem Value="~/WebUserControl.ascx|300" Enabled="true">Sample2</asp:ListItem>
            <asp:ListItem Value="~/WebUserControl.ascx|450" Enabled="true">Sample3</asp:ListItem>
        </asp:CheckBoxList>
       
       
        <asp:Button runat="server" ID="Button1" Text="Add Selected" OnClick="AddSelected_Click" />
    </div>

</asp:Content>

.CS:

using System;
using System.Collections;
using System.Configuration;
using System.Data;
using System.Web;
using System.Linq;
using System.Web.Security;
using System.Web.UI;
using System.Web.UI.HtmlControls;
using System.Web.UI.WebControls;
using System.Web.UI.WebControls.WebParts;
using System.Web.Script.Serialization;
using System.Collections.Generic;
using System.Text;

using Telerik.Web.UI;

public partial class Default2 : System.Web.UI.Page
{
    private const string cookiename = "__example_website";

    protected void Page_Load()
    {

    }

    protected void RadDockLayout1_LoadDockLayout(object sender, DockLayoutEventArgs e)
    {
        HttpCookie positionsCookie = Request.Cookies[cookiename];
        if (!Object.Equals(positionsCookie, null))
        {
            string serializedPositionsAndIndices = positionsCookie.Value;
            if (!string.IsNullOrEmpty(serializedPositionsAndIndices))
            {
                JavaScriptSerializer serializer = new JavaScriptSerializer();
                string[] positionsAndIndices = serializer.Deserialize<string[]>(serializedPositionsAndIndices);
                e.Positions = serializer.Deserialize<Dictionary<string, string>>(positionsAndIndices[0]);
                e.Indices = serializer.Deserialize<Dictionary<string, int>>(positionsAndIndices[1]);
            }
        }
    }

    protected void RadDockLayout1_SaveDockLayout(object sender, DockLayoutEventArgs e)
    {
        JavaScriptSerializer serializer = new JavaScriptSerializer();
        string serializedPositions = serializer.Serialize(e.Positions);
        string serializedIndices = serializer.Serialize(e.Indices);

        HttpCookie positionsCookie = new HttpCookie(cookiename,
            serializer.Serialize(new string[] { serializedPositions, serializedIndices }));

        //Ensure that the cookie will not expire soon
        positionsCookie.Expires = DateTime.Now.AddYears(1);
        Response.Cookies.Add(positionsCookie);

    }

    private RadDock CreateRadDock(string controlpath, string title, int width)
    {
        RadDock dock = new RadDock();
        dock.UniqueName = Guid.NewGuid().ToString();
        dock.ID = string.Format("RadDock{0}", dock.UniqueName);
        dock.Title = title;
        Control control = LoadControl(controlpath);

        dock.ContentContainer.Controls.Add(control);
        dock.Width = Unit.Pixel(width);
        dock.DockMode = DockMode.Docked;

        dock.Commands.Add(new DockCloseCommand());
        dock.Commands.Add(new DockExpandCollapseCommand());
        dock.Command += new DockCommandEventHandler(dock_Command);

        return dock;
    }
    void dock_Command(object sender, DockCommandEventArgs e)
    {
        if (e.Command.Name == "Close")
        {
            ScriptManager.RegisterStartupScript(
            UpdatePanel1,
            this.GetType(),
            "RemoveDock",
            string.Format(@"function _removeDock() {{
                    Sys.Application.remove_load(_removeDock);
                    $find('{0}').undock();
                    $get('{1}').appendChild($get('{0}'));
                    $find('{0}').doPostBack('DockPositionChanged');
                    }};
                    Sys.Application.add_load(_removeDock);", ((RadDock)sender).ClientID, UpdatePanel1.ClientID),
                    true);
        }
    }
    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;

        AsyncPostBackTrigger saveStateTrigger = new AsyncPostBackTrigger();
        saveStateTrigger.ControlID = dock.ID;
        saveStateTrigger.EventName = "DockPositionChanged";
        UpdatePanel1.Triggers.Add(saveStateTrigger);

        saveStateTrigger = new AsyncPostBackTrigger();
        saveStateTrigger.ControlID = dock.ID;
        saveStateTrigger.EventName = "Command";
        UpdatePanel1.Triggers.Add(saveStateTrigger);
    }

    protected void AddSelected_Click(Object sender, EventArgs e)
    {
        List<RadDock> add_docks = new List<RadDock>();
        List<RadDock> remove_docks = new List<RadDock>();

        foreach (ListItem li in checkboxlist.Items)
        {
            bool exists = RadDockZone1.Docks.Where(d => d.Title == li.Text).Count() > 0;
            if (li.Selected)
            {
                if (!exists)
                {
                    string[] values = li.Value.Split('|');
                    RadDock dock = CreateRadDock(values[0], li.Text, Int32.Parse(values[1]));

                    UpdatePanel1.ContentTemplateContainer.Controls.Add(dock);

                    add_docks.Add(dock);

                    CreateSaveStateTrigger(dock);
                }
            }
            else
            {
                if (exists)
                {
                    RadDock dock = RadDockZone1.Docks.FirstOrDefault(cds => cds.Title == li.Text);
                    remove_docks.Add(dock);
                }
            }
        }

        if (add_docks.Count > 0)
        {
            StringBuilder script = new StringBuilder();
            script.Append(@"function _addDock() {{");
            script.AppendLine();
            script.Append(@"Sys.Application.remove_load(_addDock); ");
            script.AppendLine();

            foreach (RadDock d in add_docks)
            {
                script.AppendFormat(@"$find('{0}').dock($find('{1}'));", RadDockZone1.ClientID, d.ClientID);
                script.AppendLine();
            }

            script.AppendFormat(@"$find('{0}').doPostBack('DockPositionChanged');", add_docks[0].ClientID);
            script.AppendLine();
            script.Append(@"}};");
            script.AppendLine();
            script.Append(@"Sys.Application.add_load(_addDock);");
            script.AppendLine();

            ScriptManager.RegisterStartupScript(
                this,
                this.GetType(),
                "AddDocks",
                script.ToString(),
                true);
        }
        if (remove_docks.Count > 0)
        {
            StringBuilder r_script = new StringBuilder();

            r_script.AppendLine(@"function _removeDock() {{");
            r_script.AppendLine("Sys.Application.remove_load(_removeDock);");

            foreach (RadDock d in remove_docks)
            {
                r_script.AppendFormat(@"$find('{0}').undock();", d.ClientID);
                r_script.AppendLine();
                r_script.AppendFormat(@"$get('{1}').appendChild($get('{0}'));", d.ClientID, UpdatePanel1.ClientID);
                r_script.AppendLine();

                // Close the raddock - to hide it in the updatepanel
                d.Closed = true;
            }

            r_script.AppendFormat(@"$find('{0}').doPostBack('DockPositionChanged');", remove_docks[0].ClientID);
            r_script.AppendLine();
            r_script.AppendLine(@"}};");
            r_script.AppendLine(@"Sys.Application.add_load(_removeDock);");

            ScriptManager.RegisterStartupScript(
                this,
                this.GetType(),
                "RemoveDocks",
                r_script.ToString(),
                true);
        }
    }
}

6 Answers, 1 is accepted

Sort by
0
Dimcho
Telerik team
answered on 16 May 2008, 11:06 AM
Hello Lee,

In our online demo Dynamically Created Docks we are adding the newly created dock in a hidden update panel and then move it to a RadDockZone. The UpdatePanel control has a trigger which specifies which postback control and event will make the panel update its content. This postback control is an asp button outside the panel.
I noticed that you haven't set a trigger to the button which you use to  starts the process of dock creation. Thus, when the dock is added to the page a postback occurs. If you want to add docks without postback you have to modify your code like this :

<asp:updatepanel runat="server" id="UpdatePanel1">  
   <triggers> 
      <asp:asyncpostbacktrigger controlid="Button1" eventname="Click" /> 
   </triggers> 
</asp:updatepanel> 

If you create RadDock controls dynamically you should do it in the Init event of the page, in order to allow the RadDockLayout to automatically manage their positions. You could create RadDock controls in other events, but you should recreate them in Init when the next postback or AJAX request occurs.
The approach is shown in the above mentioned demo so you should follow it.  

Best wishes,
Dimcho
the Telerik team

Instantly find answers to your questions at the new Telerik Support Center
0
Developer
Top achievements
Rank 1
answered on 16 May 2008, 11:43 AM
Hi Dimcho,

Thanks for the response and pointing out the updatepanel trigger. That has sorted adding the controls initially.

I am trying to recreate RadDocks after postback, and will try to make this happen in the page init definatly. What I want to know is how to recreate the RadDocks from the cookie information, the example shows you how to do it from the session, and I have used the other example that shows you how to serialize the state on Load/Save to a cookie, but the bit I'm missing is how to recreate the RadDocks from the cookie information in the page init.

The example does this in page init:

    for (int i = 0; i < CurrentDockStates.Count; i++)
    {
        RadDock dock =     CreateRadDockFromState(CurrentDockStates[i]);
        RadDockLayout1.Controls.Add(dock);
        CreateSaveStateTrigger(dock);
    }
Which calls this CreateRadDockFromState function:

        private RadDock CreateRadDockFromState(DockState state)
        {
            RadDock dock = new RadDock();
            dock.ID = string.Format("RadDock{0}", state.UniqueName);
            dock.ApplyState(state);
            dock.Command += new DockCommandEventHandler(dock_Command);
            dock.Commands.Add(new DockCloseCommand());
            dock.Commands.Add(new DockExpandCollapseCommand());

            return dock;
        }

I want to know how to rewrite this CreateRadDockFromState function so it works from the cookie information instead of a DockState object. I'm not sure on how to do this as the DockState seems to save different information than when I serialize the positions into the cookie. Any hints greatly welcomed! :)

Thanks,
Lee.

0
Accepted
Dimcho
Telerik team
answered on 16 May 2008, 04:27 PM
Hi Lee,
I used your code to prepare a simple page that demonstrates how you can get the desired result - please find it attached.

Sincerely yours,
Dimcho
the Telerik team

Instantly find answers to your questions at the new Telerik Support Center
0
Accepted
Developer
Top achievements
Rank 1
answered on 19 May 2008, 03:39 PM
Hi Dimcho,

Thanks, thats awsome, much appreciated :)

Cheers,
Lee.
0
Anahi
Top achievements
Rank 1
answered on 18 Jan 2011, 10:04 PM
Hi
I want to now how is the code but in VB!
0
Pero
Telerik team
answered on 21 Jan 2011, 01:49 PM
Hello Anahi,

Similar example can be found on our online demos site: http://demos.telerik.com/aspnet-ajax/dock/examples/myportal/defaultvb.aspx. The part of the code that saves the state in cookies can be converted using the following conversion tool: http://converter.telerik.com/.

Kind regards,
Pero
the Telerik team
Browse the vast support resources we have to jump start your development with RadControls for ASP.NET AJAX. See how to integrate our AJAX controls seamlessly in SharePoint 2007/2010 visiting our common SharePoint portal.
Tags
Dock
Asked by
Developer
Top achievements
Rank 1
Answers by
Dimcho
Telerik team
Developer
Top achievements
Rank 1
Anahi
Top achievements
Rank 1
Pero
Telerik team
Share this question
or