Dynamic controls and cookies.

7 posts, 2 answers
  1. Developer
    Developer avatar
    5 posts
    Member since:
    May 2007

    Posted 13 May 2008 Link to this post

    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);
            }
        }
    }

  2. Dimcho
    Admin
    Dimcho avatar
    45 posts

    Posted 16 May 2008 Link to this post

    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
  3. UI for ASP.NET Ajax is Ready for VS 2017
  4. Developer
    Developer avatar
    5 posts
    Member since:
    May 2007

    Posted 16 May 2008 Link to this post

    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.

  5. Answer
    Dimcho
    Admin
    Dimcho avatar
    45 posts

    Posted 16 May 2008 Link to this post

    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
  6. Answer
    Developer
    Developer avatar
    5 posts
    Member since:
    May 2007

    Posted 19 May 2008 Link to this post

    Hi Dimcho,

    Thanks, thats awsome, much appreciated :)

    Cheers,
    Lee.
  7. Anahi
    Anahi avatar
    2 posts
    Member since:
    Jan 2011

    Posted 18 Jan 2011 Link to this post

    Hi
    I want to now how is the code but in VB!
  8. Pero
    Admin
    Pero avatar
    1156 posts

    Posted 21 Jan 2011 Link to this post

    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.
Back to Top
UI for ASP.NET Ajax is Ready for VS 2017