I have a control I that contains a DockLayout.
In the OnInit method of this control, I call a method to create a Dock and then populate it. Once that's done, this gets called...
void
InitializeDock(RadDock DockToInitialize, DockState LoadedState)
{
DockToInitialize.ID =
string
.Format(
"Dock{0}"
, LoadedState.UniqueName);
GetLayoutControl().Controls.Add(DockToInitialize);
if
(!IsPostBack)
{
GetAjaxifiedPanel().Controls.Add(DockToInitialize);
}
if
(String.IsNullOrEmpty(LoadedState.DockZoneID))
{
RadDockZone dz = (RadDockZone)FindControl(
"RadDockZone2"
);
if
(dz !=
null
)
{
LoadedState.DockZoneID = dz.ClientID;
}
}
DockToInitialize.ApplyState(LoadedState);
}
All good so far.
At some point in the cycle, OnSaveDockLayout gets called. Even though the object that I'm using to create and populate the layout knows about my Dock, and I can see it in the appropriate DockZone, GetResgisteredDocksState() always returns an empty List<DockStates>.
I thought it might me something to do with the call to ApplyState() so I just created the Dock and calleddock.Dock(dockZone) on it and still got the empty list when OnSaveDockLayout was called.
What process is it that causes the source used by OnSaveDockLayout to be populated?
--
Stuart
6 Answers, 1 is accepted
However, if anyone has any other ideas, I'd love to hear me!
--
Stuart
Really, I'll take wild ass guesses at this point!
When the page loads, I have a session object that contains details of the docks to load. I load 'em. I do this in the OnInit event.
Sometime after this, the OnLoadDockLayout event fires and my code updates e.Positions and e.Indices.
Then (before I do anything on the page, ie before the initial page load finishes) the OnSaveDockLayout method fires and GetRegisteredDocksState() always returns and empty list.
I'm now fairly sure that the fact that the DockLayout controls are being loaded dynamically isn';t the cause of the problem, but if you know better, please let me know.
--
Stuart
Note that the RadDockLayout control only manages the layout of RadDock and RadDockZone controls that are contained in its Controls collections. Please ensure that every time you are adding a RadDock on your page you are inserting it in the RadDockLayout as shown below:
RadDockLayout1.Controls.Add(dock);
// 'dock' is the instance of RadDock that you will add in the page
Also, I would recommend checking the help article Dynamically Creating RadDock Controls, which describes the correct approach for dynamically adding new dock controls and persisting their state through postback. The following online demos contain useful examples that implement this method:
- Dock / Dynamically Created Docks;
- Dock / My Portal;
I hope this will help you resolve your problem. If you are still having difficulties after examining the provided information, please open a regular support ticket and isolate the issue in a simple, runnable page so that I can pinpoint the exact cause after inspecting your scenario.
Regards,
Slav
the Telerik team
I know that the RegisteredDocks property of my DockLayout never seems to have anything in it, however, the RegisteredZones property does.
What's more, and prolly, what's more important, is that each member of the Docks collection of each of the RegisteredZones does have my docks in it.
So, I've abandoned the call to GetRegisteredDocksState() in favour of this ...
protected
List<DockState> GetWidgetStates()
{
List<DockState> result =
new
List<DockState>();
GetLayoutControl().RegisteredZones.ToList().ForEach(zone =>
{
zone.Docks.ToList().ForEach(dock =>
{
result.Add(
new
DockState
{
Closed = dock.Closed,
Collapsed = dock.Collapsed,
DockZoneID = dock.DockZoneID,
ExpandedHeight = dock.ExpandedHeight,
Height = dock.Height,
Index = dock.Index,
Left = dock.Left,
Pinned = dock.Pinned,
Resizable = dock.Resizable,
Tag = dock.Tag,
Text = dock.Text,
Title = dock.Title,
Top = dock.Top,
UniqueName = dock.UniqueName,
Width = dock.Width
});
});
});
return
result;
}
So far, with my simple layouts and limited number of docks, this works.
--
Stuart
Hello my friend.
> Note that the RadDockLayout control only manages the layout of RadDock
> and RadDockZone controls that are contained in its Controls collections
The RadDockZone controls are added in the markup...
<%@ Control Language="C#" AutoEventWireup="true" CodeBehind="2x1H.ascx.cs" Inherits="UEAPL.WebApplication.Controls.Collaborate.Dashboard.Layouts._2x1H" %>
<%@ Register Assembly="Telerik.Web.UI" Namespace="Telerik.Web.UI" TagPrefix="telerik" %>
<
telerik:RadDockLayout
runat
=
"server"
ID
=
"RadDockLayout1"
>
<
telerik:RadDockZone
runat
=
"server"
ID
=
"RadDockZone1"
FitDocks
=
"false"
Orientation
=
"Horizontal"
style
=
"background-color:#E3FFE3; float:left; margin:10px;"
Width
=
"96%"
Height
=
"40%"
>
</
telerik:RadDockZone
>
<
asp:Panel
runat
=
"server"
ID
=
"sep1"
Height
=
"10px"
/>
<
telerik:RadDockZone
runat
=
"server"
ID
=
"RadDockZone2"
FitDocks
=
"false"
Orientation
=
"Horizontal"
style
=
"background-color:#FFE4E3; float:left; margin:10px;"
Width
=
"96%"
Height
=
"40%"
>
</
telerik:RadDockZone
>
<
div
style
=
"display: none"
>
Hidden Ajaxified asp:Panel, which is used to receive the new dock controls. We will move
them with script to the desired initial dock zone.
<
asp:Panel
ID
=
"Panel1"
runat
=
"server"
>
</
asp:Panel
>
</
div
>
</
telerik:RadDockLayout
>
The OnInit event loads the docks from storage and stores them in the Dashboard.Widgets collection in the following code (Widgets is List<DockState>)...
protected
void
LoadWidgetsFromSavedState()
{
if
(Dashboard.Widgets !=
null
)
{
RadDock dock =
null
;
for
(
int
i = 0; i < Dashboard.Widgets.Count; i++)
{
DockState state = Dashboard.Widgets[i];
if
(!state.Closed && state.Tag !=
null
)
{
switch
(state.Tag)
{
// create the dock and load the content
}
}
InitializeDock(dock, state);
}
}
}
void
InitializeDock(RadDock DockToInitialize, DockState LoadedState)
{
DockToInitialize.ID =
string
.Format(
"Dock{0}"
, LoadedState.UniqueName);
GetLayoutControl().Controls.Add(DockToInitialize);
if
(!IsPostBack)
{
GetAjaxifiedPanel().Controls.Add(DockToInitialize);
}
if
(String.IsNullOrEmpty(LoadedState.DockZoneID))
{
RadDockZone dz = (RadDockZone)FindControl(
"RadDockZone2"
);
if
(dz !=
null
)
{
LoadedState.DockZoneID = dz.ClientID;
}
}
DockToInitialize.ApplyState(LoadedState);
}
The code in InitializeDock() is pretty much a lift from the code the Pero@Telerik supplied in this forum article.
As you can see, the docks are added to the Controls collection of the layout.
Thanks for the pointers to the help and demo articles; I'd actually used those in creating the code I've got so far.
--
Stuart
Please provide more information on the approach that you are using when adding RadDocks initially, as this is not covered by the code samples. Also, are you loading dynamically the user control that contains the RadDockLayout and if so, on which event of the page lifecycle are you doing this?
A possible solution in your case could be to not add the recreated RadDock control in the Controls collection of the AJAXified Panel and only in the RadDockLayout, as shown in the sample below:
void
InitializeDock(RadDock DockToInitialize, DockState LoadedState)
{
DockToInitialize.ID =
string
.Format(
"Dock{0}"
, LoadedState.UniqueName);
GetLayoutControl().Controls.Add(DockToInitialize);
if
(String.IsNullOrEmpty(LoadedState.DockZoneID))
{
RadDockZone dz = (RadDockZone)FindControl(
"RadDockZone2"
);
if
(dz !=
null
)
{
LoadedState.DockZoneID = dz.ClientID;
}
}
DockToInitialize.ApplyState(LoadedState);
}
This change may cause problems with the ViewState of the RadDock's content, which can be resolved by attaching the ViewStateModeById attribute, as explained in this forum thread. This will force the ViewState to be applied to a control based upon the ID of the control and not the index on the control.
If the problem persists after trying the suggested solution, please open a support ticket and send a simple, runnable page that isolates your scenario, so that I can inspect it and provide a more to the point answer.
All the best,
Slav
the Telerik team