<
telerik:RadDockLayout
runat
=
"server"
ID
=
"QuestionsDockLayout"
>
<
telerik:RadDockZone
ID
=
"RadDockZone1"
runat
=
"server"
/>
</
telerik:RadDockLayout
>
private
bool
_shouldSavesState =
false
;
protected
void
Page_Init(
object
sender, EventArgs e)
{
QuestionsDockLayout.SaveDockLayout += QuestionsDockLayout_SaveDockLayout;
LoadQuestions();
}
private
void
LoadQuestions()
{
foreach
(var zone
in
QuestionsDockLayout.RegisteredZones)
{
zone.Docks.Clear();
zone.Controls.Clear();
}
if
(!
string
.IsNullOrEmpty(XmlNode_Page))
{
XmlDocument xmldoc_page =
new
XmlDocument();
xmldoc_page.Load(
new
StringReader(XmlNode_Page));
XmlNodeList nodePages = xmldoc_page.SelectNodes(
"//Question"
);
if
(nodePages !=
null
&& nodePages.Count > 0)
{
for
(
int
i = 0; i < nodePages.Count; i++)
{
RadDock radDock =
new
RadDock();
radDock.ID =
"dockPanel_"
+
this
.ID +
"_Q"
+ i;
radDock.AutoPostBack =
true
;
radDock.Resizable =
false
;
radDock.DockMode = DockMode.Docked;
radDock.DockHandle = DockHandle.None;
radDock.OnClientInitialize =
"SetHandleDock"
;
QuestionsDockLayout.RegisteredZones[0].Controls.Add(radDock);
XmlNode XnodeQuestion = nodePages[i];
UC_SurveyQuestion SQ = (UC_SurveyQuestion)LoadControl(
"~/UserControls/UC_SurveyQuestion.ascx"
);
SQ.ID = XnodeQuestion.Attributes[
"id"
].Value;
SQ.XmlNode_Question = XnodeQuestion.OuterXml;
SQ.Page_ID =
this
.ID;
HtmlImage img = SQ.FindControl(
"Handle"
)
as
HtmlImage;
img.ClientIDMode = System.Web.UI.ClientIDMode.Static;
img.ID =
"Handle_"
+ radDock.ClientID;
radDock.ContentTemplate =
new
CompiledTemplateBuilder(parent =>
parent.Controls.Add(SQ)
);
radDock.DockPositionChanged += dock_DockPositionChanged;
}
}
}
private
void
dock_DockPositionChanged(
object
sender, DockPositionChangedEventArgs e)
{
//if dock position was changed set a flag for saving dock state
_shouldSavesState =
true
;
}
private
void
QuestionsDockLayout_SaveDockLayout(
object
sender, DockLayoutEventArgs e)
{
//Save dock panels state in user's profile
if
(_shouldSavesState)
{
List<DockState> lst = QuestionsDockLayout.GetRegisteredDocksState();
}
}
SaveDockLayout event GetRegistered
DockState method returns the same state of docks as when they are added.<%@ Page Title="" Language="vb" AutoEventWireup="false" MasterPageFile="MasterPage.Master" CodeBehind="DockingTest.aspx.vb" Inherits="DockingTest" %>
<%@ Register Assembly="Telerik.Web.UI" Namespace="Telerik.Web.UI" TagPrefix="telerik" %>
<%@ Register tagPrefix="ctl" tagName="GridTest" src="GridTest.ascx" %>
<
asp:Content
ID
=
"Content1"
ContentPlaceHolderID
=
"AppContentTitle"
runat
=
"server"
>
</
asp:Content
>
<
asp:Content
ID
=
"Content2"
ContentPlaceHolderID
=
"AppContent"
runat
=
"server"
>
<
asp:Label
ID
=
"lblMessage"
runat
=
"server"
EnableViewState
=
"false"
Visible
=
"false"
/>
<
form
id
=
"Form1"
runat
=
"server"
>
<
ctl:GridTest
ID
=
"ctlGridTest"
runat
=
"server"
Visible
=
"true"
/>
</
form
>
</
asp:Content
>
<%@ Control Language="vb" AutoEventWireup="false" CodeBehind="GridTest.ascx.vb" Inherits="GridTest" %>
<%@ Register Assembly="Telerik.Web.UI" Namespace="Telerik.Web.UI" TagPrefix="telerik" %>
<
asp:ScriptManager
ID
=
"ScriptManager1"
runat
=
"server"
/>
<
asp:Label
ID
=
"lblMessage"
runat
=
"server"
EnableViewState
=
"false"
Visible
=
"false"
/>
<
telerik:RadGrid
ID
=
"rgGrid"
runat
=
"server"
Skin
=
"Default"
GridLines
=
"both"
BorderStyle
=
"outset"
BorderWidth
=
"3"
PageSize
=
"15"
AllowPaging
=
"True"
style
=
"width:100%;"
AutoGenerateColumns
=
"false"
AllowSorting
=
"true"
ShowStatusBar
=
"true"
AllowAutomaticDeletes
=
"false"
AllowAutomaticInserts
=
"false"
ItemStyle-BackColor
=
"AliceBlue"
AlternatingItemStyle-BackColor
=
"Lightyellow"
AllowAutomaticUpdates
=
"false"
>
<
PagerStyle
Mode
=
"Advanced"
/>
<
MasterTableView
Width
=
"100%"
DataKeyNames
=
"ZONE_ID"
TableLayout
=
"Auto"
CommandItemDisplay
=
"TopAndBottom"
EditMode
=
"popUp"
ExpandCollapseColumn-ButtonType
=
"pushButton"
Name
=
"Template"
ShowHeadersWhenNoRecords
=
"true"
>
<
Columns
>
<
telerik:GridEditCommandColumn
UniqueName
=
"Edit"
>
</
telerik:GridEditCommandColumn
>
<
telerik:GridBoundColumn
DataField
=
"ZONE_ID"
HeaderText
=
"Zone ID"
UniqueName
=
"ZONE_ID"
>
</
telerik:GridBoundColumn
>
<
telerik:GridBoundColumn
DataField
=
"ZONE_TYPE"
HeaderText
=
"Zone Type"
UniqueName
=
"ZONE_TYPE"
>
</
telerik:GridBoundColumn
>
<
telerik:GridBoundColumn
DataField
=
"ZONE_CONTENT"
HeaderText
=
"Zone Content"
UniqueName
=
"ZONE_CONTENT"
>
</
telerik:GridBoundColumn
>
<
telerik:GridButtonColumn
ConfirmText
=
"W A R N I N G !!! You are about to delete this zone. Do you still want to continue?"
ConfirmDialogType
=
"RadWindow"
ConfirmTitle
=
"Delete"
ButtonType
=
"LinkButton"
CommandName
=
"Delete"
Text
=
"Delete"
UniqueName
=
"DeleteColumn"
>
</
telerik:GridButtonColumn
>
</
Columns
>
<
EditFormSettings
UserControlName
=
"DocksDynamic.ascx"
EditFormType
=
"WebUserControl"
PopUpSettings-Modal
=
"true"
>
</
EditFormSettings
>
</
MasterTableView
>
</
telerik:RadGrid
>
<%@ Control Language="vb" AutoEventWireup="false" CodeBehind="DocksDynamic.ascx.vb" Inherits="DocksDynamic" %>
<%@ Register TagPrefix="telerik" Namespace="Telerik.Web.UI" Assembly="Telerik.Web.UI" %>
<
asp:Button
runat
=
"server"
CssClass
=
"button"
ID
=
"ButtonAddDock"
Text
=
"Add Dock"
OnClick
=
"ButtonAddDock_Click"
/>
<
asp:Button
runat
=
"server"
ID
=
"ButtonPostback"
CssClass
=
"button"
Text
=
"Make Postback"
/>
<
br
/>
<
br
/>
<
asp:UpdatePanel
runat
=
"server"
ID
=
"UpdatePanel1"
>
<
ContentTemplate
>
<
telerik:RadDockLayout
runat
=
"server"
ID
=
"RadDockLayout1"
OnSaveDockLayout
=
"RadDockLayout1_SaveDockLayout"
OnLoadDockLayout
=
"RadDockLayout1_LoadDockLayout"
>
<
telerik:RadDockZone
runat
=
"server"
ID
=
"RadDockZone1"
Width
=
"300"
MinHeight
=
"200"
Style
=
"float: left; margin-right: 20px;"
>
</
telerik:RadDockZone
>
<
telerik:RadDockZone
Width
=
"300"
MinHeight
=
"200"
runat
=
"server"
ID
=
"RadDockZone2"
Style
=
"float: left;"
>
</
telerik:RadDockZone
>
</
telerik:RadDockLayout
>
</
ContentTemplate
>
<
Triggers
>
<
asp:AsyncPostBackTrigger
ControlID
=
"ButtonAddDock"
EventName
=
"Click"
/>
</
Triggers
>
</
asp:UpdatePanel
>
Below is code-behind for DocksDynamic.ascx.vb:
Imports Telerik.Web.UI
Partial Public Class DocksDynamic
Inherits System.Web.UI.UserControl
Private Property CurrentDockStates() As List(Of DockState)
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.
Dim _currentDockStates As List(Of DockState) = DirectCast(Session("CurrentDockStatesDynamicDocks"), List(Of DockState))
If [Object].Equals(_currentDockStates, Nothing) Then
_currentDockStates = New List(Of DockState)()
Session("CurrentDockStatesDynamicDocks") = _currentDockStates
End If
Return _currentDockStates
End Get
Set(value As List(Of DockState))
Session("CurrentDockStatesDynamicDocks") = value
End Set
End Property
Private Function CreateRadDockFromState(state As DockState) As RadDock
Dim dock As New RadDock()
dock.DockMode = DockMode.Docked
dock.ID = String.Format("RadDock{0}", state.UniqueName)
dock.ApplyState(state)
dock.Commands.Add(New DockCloseCommand())
dock.Commands.Add(New DockExpandCollapseCommand())
Return dock
End Function
Private Function CreateRadDock() As RadDock
Dim docksCount As Integer = CurrentDockStates.Count
Dim dock As New RadDock()
dock.DockMode = DockMode.Docked
dock.UniqueName = Guid.NewGuid().ToString().Replace("-", "a")
dock.ID = String.Format("RadDock{0}", dock.UniqueName)
dock.Title = "Dock"
dock.Text = String.Format("Added at {0}", DateTime.Now)
dock.Width = Unit.Pixel(300)
dock.Commands.Add(New DockCloseCommand())
dock.Commands.Add(New DockExpandCollapseCommand())
Return dock
End Function
Private Sub CreateSaveStateTrigger(dock As RadDock)
'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
AddHandler dock.DockPositionChanged, AddressOf Me.DockPositionChanged
'Dim saveStateTrigger As 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)
End Sub
Protected Sub DockPositionChanged(ByVal sender As Object, ByVal e As DockPositionChangedEventArgs)
Dim str As String = ""
'Put a break here
End Sub
Private Sub Page_Init(sender As Object, e As System.EventArgs) Handles Me.Init
'Recreate the docks in order to ensure their proper operation
Dim i As Integer = 0
While i < CurrentDockStates.Count
Dim dock As RadDock = 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)
System.Math.Max(System.Threading.Interlocked.Increment(i), i - 1)
End While
End Sub
Protected Sub RadDockLayout1_LoadDockLayout(sender As Object, e As DockLayoutEventArgs) Handles RadDockLayout1.LoadDockLayout
'Populate the event args with the state information. The RadDockLayout control
' will automatically move the docks according that information.
For Each state As DockState In CurrentDockStates
e.Positions(state.UniqueName) = state.DockZoneID
e.Indices(state.UniqueName) = state.Index
Next
End Sub
Protected Sub RadDockLayout1_SaveDockLayout(sender As Object, e As DockLayoutEventArgs) Handles RadDockLayout1.SaveDockLayout
'Save the dock state in the page Session. This will enable us
' to recreate the dock in the next Page_Init.
CurrentDockStates = RadDockLayout1.GetRegisteredDocksState()
End Sub
Protected Sub ButtonAddDock_Click(sender As Object, e As System.EventArgs)
Dim dock As RadDock = CreateRadDock()
RadDockZone1.Controls.Add(dock)
CreateSaveStateTrigger(dock)
End Sub
End Class
The issue that I'm facing is this.
With the setup above (SETUP 1): DocksDynamics.ascx is used as an EditForm user control for the GridTest.ascx user control's RadGrid that is used by the DockingTest.aspx page ...
For some reason, the RadDockLayout1_LoadDockLayout event is never fired when I click Edit in any of the records in the RadGrid or whenever I add a dock or move a dock from one zone to another.
Furthermore, when I click the Add Dock button, it is able to add one dock, but when I click it a second time, I get the following error message:
Microsoft JScript runtime error: Sys.WebForms.PageRequestManagerServerErrorException: Cannot unregister UpdatePanel with ID 'UpdatePanel1' since it was not registered with the ScriptManager. This might occur if the UpdatePanel was removed from the control tree and later added again, which is not supported.
Parameter name: updatePanel
BUT, if I change my setup to be like this (SETUP 2): DocksDynamics.ascx (with a Script Manager added to it) is used directly in DockingTest.aspx page and not from within a RadGrid in a separate user control, the RadDockLayout1_LoadDockLayout event gets fired.
<%@ Page Title="" Language="vb" AutoEventWireup="false" MasterPageFile="MasterPage.Master" CodeBehind="DocksTest.aspx.vb" Inherits="DocksTest" %>
<%@ Register Assembly="Telerik.Web.UI" Namespace="Telerik.Web.UI" TagPrefix="telerik" %>
<%@ Register tagPrefix="ctl" tagName="DocksDynamic" src="DocksDynamic.ascx" %>
<
asp:Content
ID
=
"Content1"
ContentPlaceHolderID
=
"AppContentTitle"
runat
=
"server"
>
</
asp:Content
>
<
asp:Content
ID
=
"Content2"
ContentPlaceHolderID
=
"AppContent"
runat
=
"server"
>
<
asp:Label
ID
=
"lblMessage"
runat
=
"server"
EnableViewState
=
"false"
Visible
=
"false"
/>
<
form
id
=
"Form1"
runat
=
"server"
>
<
ctl:DocksDynamic
ID
=
"ctlDocksDynamic"
runat
=
"server"
Visible
=
"true"
/>
</
form
>
</
asp:Content
>
<
telerik:RadToolTip
runat
=
"server"
ID
=
"RadToolTipInsert"
Position
=
"TopLeft"
ShowEvent
=
"FromCode"
Width
=
"400px"
RelativeTo
=
"Element"
OnClientBeforeShow
=
"CheckIfShowInsert"
Skin
=
"Sitefinity"
ManualClose
=
"True"
Animation
=
"Fade"
EnableShadow
=
"True"
Title="<span
class
=
'MsgTextoToolTip'
><
b
> No es posible guardar debido a lo siguiente:</
b
></
span
> "
RenderInPageRoot="True">
<
asp:ValidationSummary
ID
=
"valSumaryInsert"
runat
=
"server"
ValidationGroup
=
"insert_group"
/>
</
telerik:RadToolTip
>
<
telerik:RadToolTip
ID
=
"RadToolTipUpdate"
runat
=
"server"
Animation
=
"Fade"
EnableShadow
=
"True"
ManualClose
=
"True"
OnClientBeforeShow
=
"CheckIfShowUpdate"
Position
=
"TopLeft"
RelativeTo
=
"Element"
ShowEvent
=
"FromCode"
Width
=
"400px"
Title="<span
class
=
'MsgTextoToolTip'
><
b
> No es posible guardar debido a lo siguiente:</
b
></
span
> "
RenderInPageRoot="True" IsClientID="True" TargetControlID="ToolTipsPositionEditMode"
>
<
asp:ValidationSummary
ID
=
"valSummaryUpdate"
runat
=
"server"
ValidationGroup
=
"update_group"
/>
</
telerik:RadToolTip
>
<
EditItemTemplate
>
<
asp:ImageButton
ID
=
"btnUpdate"
runat
=
"server"
BorderStyle
=
"None"
BorderWidth
=
"0px"
commandname
=
"Update"
ImageUrl
=
"~/Imagenes/PedidoExpress/diskyellow16.png"
ValidationGroup
=
"update_group"
onclientclick
=
"ShowTooltipUpdate();"
ToolTip
=
"Guardar los cambios realizados"
/>
<
InsertItemTemplate
>
<
asp:ImageButton
ID
=
"btnInsert"
runat
=
"server"
BorderStyle
=
"None"
BorderWidth
=
"0px"
commandname
=
"PerformInsert"
ImageUrl
=
"~/Imagenes/PedidoExpress/diskgreen16.png"
ValidationGroup
=
"insert_group"
onclientclick
=
"ShowTooltipInsert()"
ToolTip
=
"Agregar beneficiario al pedido"
/>
function
CheckIfShowInsert(sender, args) {
var
summaryElem = document.getElementById(
"<%= valSumaryInsert.ClientID %>"
);
if
(summaryElem.style.display ==
"none"
) {
args.set_cancel(
true
);
}
}
function
ShowTooltipInsert() {
window.setTimeout(
function
() {
var
tooltip = $find(
"<%= RadToolTipInsert.ClientID %>"
)
tooltip.show();
}, 10);
}
function
CheckIfShowUpdate(sender, args) {
var
summaryElem = document.getElementById(
"<%= valSummaryUpdate.ClientID %>"
);
if
(summaryElem.style.display ==
"none"
) {
//API: if there are no errors, do not show the tooltip
args.set_cancel(
true
);
}
}
function
ShowTooltipUpdate() {
var
tooltip = $find(
"<%= RadToolTipUpdate.ClientID %>"
)
setTimeout(
function
()
{
tooltip.show();
}, 20);
}