Persist viewstate in ITemplate child controls

Discussion in 'ASP .Net Web Controls' started by George, Nov 13, 2009.

  1. George

    George Guest

    Hello Coders,

    I have a particularly brain frying problem today. I'd appreciate it if you
    can help before I test how strong the walls of the office are.

    I have been building a custom collapsible panel control, into which I'm
    placing some custom web user controls. The viewstate of my custom
    webcontrols is not persisting between postbacks. I think this is because
    inside my collapsible panel, I override CreateChildControls (to layout my
    controls from my ITemplate) and OnInit (to call EnsureChildControls).

    I'm attaching the code for my panel (which I have been poking at for nearly
    2 days to get working).

    Sorry, but this is long. This important parts you would want to look at are
    inside the 'Overrides' region.

    Many thanks.

    Imports System
    Imports System.Collections.Generic
    Imports System.ComponentModel
    Imports System.Text
    Imports System.Web
    Imports System.Web.UI
    Imports System.Web.UI.WebControls
    Imports System.Web.UI.Design.WebControls

    Namespace Curve.WebControls

    <DefaultProperty("Text")> _
    <ToolboxData("<{0}:CollapsingPanel
    runat=server></{0}:CollapsingPanel>")> _
    <Designer(GetType(CollapsingPanelDesigner))> _
    <ParseChildren(True)> _
    Public Class CollapsingPanel
    Inherits Panel
    Implements INamingContainer

    Public Event CloseButtonClicked(ByRef self As CollapsingPanel)

    #Region " Variables "

    Private header As ITemplate
    Private content As ITemplate

    Private headerTemplateContainer As New
    CollapsingPanelTemplateContainer
    Private contentTemplateContainer As New
    CollapsingPanelTemplateContainer

    Private updatePanel As New UpdatePanel

    Private collapseStateTextBox As New TextBox

    Private expandAnimation As New AjaxControlToolkit.AnimationExtender
    Private collapseAnimation As New
    AjaxControlToolkit.AnimationExtender

    Private mainPanel As New Panel
    Private titlePanel As New Panel
    Private bodyPanel As New Panel
    Private bodyInnerPanel As New Panel
    Private titleLabel As New Label
    Private refreshButton As New ImageButton
    Private collapseButton As New ImageButton
    Private expandButton As New ImageButton
    Private closeButton As New ImageButton
    Private titleTable As New Table
    Private tr As New TableRow
    Private titleLabelCell As New TableCell
    Private titleButtonsCell As New TableCell
    Private refreshSpacer As New LiteralControl(" ")
    Private collapseSpacer As New LiteralControl(" ")
    Private closeSpacer As New LiteralControl(" ")

    #End Region

    #Region " Properties "

    <Bindable(True)> _
    <PersistenceMode(PersistenceMode.InnerProperty)> _
    <TemplateContainer(GetType(CollapsingPanelTemplateContainer))> _
    <TemplateInstance(TemplateInstance.Single)> _
    Public Property HeaderTemplate() As ITemplate
    Get
    Return header
    End Get
    Set(ByVal value As ITemplate)
    header = value
    End Set
    End Property

    <Browsable(False)> _
    <PersistenceMode(PersistenceMode.InnerProperty)> _
    <TemplateContainer(GetType(CollapsingPanelTemplateContainer))> _
    <TemplateInstance(TemplateInstance.Single)> _
    Public Property ContentTemplate() As ITemplate
    Get
    Return content
    End Get
    Set(ByVal value As ITemplate)
    content = value
    End Set
    End Property

    <Bindable(True)> _
    <Category("Appearance")> _
    <DefaultValue("")> _
    <Localizable(True)> _
    Public Property Title() As String
    Get
    Dim s As String = ViewState("Title")
    Return IIf(s = Nothing, String.Empty, s)
    End Get
    Set(ByVal value As String)
    ViewState("Title") = value
    If titleLabel IsNot Nothing Then
    titleLabel.Text = value
    End If
    End Set
    End Property

    <Bindable(True)> _
    <Category("Appearance")> _
    <DefaultValue("")> _
    <Localizable(True)> _
    Public Property IsCollapsed() As Boolean
    Get
    Dim s As String = ViewState("IsCollapsed")
    'Dim s As String = Me.Context.Items(Me.ID & "$IsCollapsed")
    Return IIf(s = Nothing, False, Convert.ToBoolean(s))
    End Get
    Set(ByVal value As Boolean)
    ViewState("IsCollapsed") = value.ToString
    End Set
    End Property

    <Bindable(True)> _
    <Category("Appearance")> _
    <DefaultValue("")> _
    <Localizable(True)> _
    Public Property IsCollapsible() As Boolean
    Get
    Dim s As String = ViewState("IsCollapsible")
    Return IIf(s = Nothing, False, Convert.ToBoolean(s))
    End Get
    Set(ByVal value As Boolean)
    ViewState("IsCollapsible") = value.ToString
    End Set
    End Property

    <Bindable(True)> _
    <Category("Appearance")> _
    <DefaultValue("")> _
    <Localizable(True)> _
    Public Property IsRefreshable() As Boolean
    Get
    Dim s As String = ViewState("IsRefreshable")
    Return IIf(s = Nothing, False, Convert.ToBoolean(s))
    End Get
    Set(ByVal value As Boolean)
    ViewState("IsRefreshable") = value
    If refreshButton IsNot Nothing Then
    refreshButton.Visible = value
    End If
    End Set
    End Property

    <Bindable(True)> _
    <Category("Appearance")> _
    <DefaultValue("")> _
    <Localizable(True)> _
    Public Property IsClosable() As Boolean
    Get
    Dim s As String = ViewState("IsClosable")
    Return IIf(s = Nothing, False, Convert.ToBoolean(s))
    End Get
    Set(ByVal value As Boolean)
    ViewState("IsClosable") = value.ToString
    If closeButton IsNot Nothing Then
    closeButton.Visible = value
    End If
    End Set
    End Property

    <Bindable(True)> _
    <Category("Appearance")> _
    <DefaultValue("")> _
    <Localizable(True)> _
    Public Property IsChildViewStateEnabled() As Boolean
    Get
    Dim s As String = ViewState("IsChildViewStateEnabled")
    Return IIf(s = Nothing, True, Convert.ToBoolean(s))
    End Get
    Set(ByVal value As Boolean)
    ViewState("IsChildViewStateEnabled") = value
    End Set
    End Property

    #End Region

    #Region " Overrides "

    Protected Overrides Sub LoadViewState(ByVal savedState As Object)
    MyBase.LoadViewState(savedState)
    End Sub

    Protected Overrides Function SaveViewState() As Object
    Return MyBase.SaveViewState()
    End Function

    Protected Overrides Sub OnInit(ByVal e As EventArgs)
    'BuildControlHeirarchy()
    EnsureChildControls()
    InitialiseControls()

    If collapseStateTextBox.Text = "True" Then
    Me.CollapsePanel()
    Else
    Me.OpenPanel()
    End If
    MyBase.OnInit(e)
    End Sub

    Protected Overrides Sub CreateChildControls()

    CreateControlHeirarchy()

    ' Disable viewstate in all controls?
    'If Not IsChildViewStateEnabled Then
    ' DisableViewState(Me)
    'End If

    ' Set all the values and properties
    'ConfigureInternalLayoutControls()
    End Sub

    'Protected Overrides Sub Render(ByVal writer As HtmlTextWriter)

    ' ' This anchor is used to allow a given collapsing panel to be
    ' ' navigated to on the page
    ' Dim anchor As New LiteralControl(String.Format("<a
    name='{0}_anchor'></a>", ID))
    ' anchor.RenderControl(writer)
    ' 'mainPanel.RenderControl(writer)
    ' updatePanel.RenderControl(writer)

    'End Sub

    Public Overrides ReadOnly Property Controls() As ControlCollection
    Get
    Return MyBase.Controls
    End Get
    End Property

    #End Region

    #Region " Events "

    Public Sub refreshButton_Click(ByVal sender As Object, ByVal e As
    ImageClickEventArgs)
    updatePanel.Update()
    End Sub

    Protected Sub closeButton_Click(ByVal sender As Object, ByVal e As
    ImageClickEventArgs)
    RaiseEvent CloseButtonClicked(Me)
    End Sub

    #End Region

    #Region " Custom Methods "

    Private Sub CreateControlHeirarchy()
    Controls.Add(updatePanel)
    updatePanel.ContentTemplateContainer.Controls.Add(mainPanel)
    mainPanel.Controls.Add(collapseStateTextBox)
    mainPanel.Controls.Add(titlePanel)
    titlePanel.Controls.Add(titleTable)
    titleTable.Rows.Add(tr)
    tr.Cells.Add(titleLabelCell)
    titleLabelCell.Controls.Add(headerTemplateContainer)

    If HeaderTemplate IsNot Nothing Then
    HeaderTemplate.InstantiateIn(headerTemplateContainer)
    If headerTemplateContainer.Controls.Count <= 1 Then
    headerTemplateContainer.Controls.Add(titleLabel)
    End If

    tr.Cells.Add(titleButtonsCell)
    titleButtonsCell.Controls.Add(refreshSpacer)
    titleButtonsCell.Controls.Add(refreshButton)
    titleButtonsCell.Controls.Add(collapseSpacer)
    titleButtonsCell.Controls.Add(collapseButton)
    titleButtonsCell.Controls.Add(collapseAnimation)
    titleButtonsCell.Controls.Add(expandButton)
    titleButtonsCell.Controls.Add(expandAnimation)
    titleButtonsCell.Controls.Add(closeSpacer)
    titleButtonsCell.Controls.Add(closeButton)
    mainPanel.Controls.Add(bodyPanel)
    bodyPanel.Controls.Add(bodyInnerPanel)

    ' Add controls to bodyInnerPanel
    contentTemplateContainer = New CollapsingPanelTemplateContainer
    bodyInnerPanel.Controls.Add(contentTemplateContainer)
    If ContentTemplate IsNot Nothing Then
    ContentTemplate.InstantiateIn(contentTemplateContainer)
    End If
    End Sub

    Private Sub InitialiseControls()
    updatePanel.UpdateMode = UpdatePanelUpdateMode.Conditional

    mainPanel.CssClass = "panel_container_group"
    mainPanel.Width = Me.Width
    bodyPanel.Width = Me.Width
    bodyPanel.Height = Me.Height
    'bodyPanel.ScrollBars = Me.ScrollBars

    titlePanel.CssClass = "panel_container_header"
    titleTable.Width = New Unit(100, UnitType.Percentage)

    titleLabel.Text = Title

    titleButtonsCell.HorizontalAlign = HorizontalAlign.Right
    titleButtonsCell.VerticalAlign = VerticalAlign.Middle

    refreshSpacer.Visible = IsRefreshable
    refreshButton.ImageUrl =
    "~/client/site_layout/icons/container_refresh.png"
    AddHandler refreshButton.Click, AddressOf Me.refreshButton_Click
    refreshButton.Visible = IsRefreshable

    collapseSpacer.Visible = IsCollapsible
    collapseButton.ImageUrl =
    "~/client/site_layout/icons/container_collapse.png"
    collapseButton.ToolTip = "Collapse"
    collapseButton.Visible = IsCollapsible

    collapseAnimation.TargetControlID = collapseButton.UniqueID
    collapseAnimation.Animations = GetCollapseAnimationXml()

    expandButton.ImageUrl =
    "~/client/site_layout/icons/container_expand.png"
    expandButton.ToolTip = "Expand"
    expandButton.Visible = IsCollapsible

    expandAnimation.TargetControlID = expandButton.UniqueID
    expandAnimation.Animations = GetExpandAnimationXml()

    If Not Me.Page.IsPostBack Then
    collapseStateTextBox.Text = IsCollapsed
    End If

    If IsCollapsible Then
    If IsCollapsed Then
    collapseButton.Style("display") = "none"
    expandButton.Style("display") = "inline"
    bodyPanel.Style("display") = "none"
    Else
    collapseButton.Style("display") = "inline"
    expandButton.Style("display") = "none"
    bodyPanel.Style("display") = "block"
    End If
    End If

    closeSpacer.Visible = IsClosable
    closeButton.ImageUrl =
    "~/client/site_layout/icons/container_close.png"
    closeButton.ToolTip = "Close"
    closeButton.OnClientClick = "return confirm('Are you sure you
    want to close this panel?');"
    AddHandler closeButton.Click, AddressOf Me.closeButton_Click
    closeButton.Visible = IsClosable

    'If CloseConfirmation IsNot Nothing AndAlso
    CloseConfirmation.Trim <> "" Then
    ' closeButton.OnClientClick = "var close = confirm('" &
    CloseConfirmation & "'); if (! close) {return false;}"
    'End If

    bodyPanel.CssClass = "panel_container"
    bodyInnerPanel.CssClass = "panel_container_inner"

    collapseStateTextBox.Style.Add("display", "none")
    collapseStateTextBox.Visible = True
    expandButton.Attributes.Add("onclick", String.Format("{0}.value
    = 'False';return false;", collapseStateTextBox.ClientID))
    collapseButton.Attributes.Add("onclick",
    String.Format("{0}.value = 'True';return false;",
    collapseStateTextBox.ClientID))
    End Sub

    ''' <summary>
    ''' Recursive function to disable viewstate on control and all of
    its children.
    ''' </summary>
    ''' <param name="c"></param>
    ''' <remarks></remarks>
    Private Sub DisableViewState(ByVal c As Control)
    'c.EnableViewState = False
    'For Each sc As Control In c.Controls
    ' sc.EnableViewState = False
    ' If sc.HasControls Then
    ' DisableViewState(sc)
    ' End If
    'Next
    End Sub

    Private Function GetCollapseAnimationXml() As String
    Dim sb As New IO.StringWriter

    sb.WriteLine("<OnClick>")
    sb.WriteLine(" <Parallel Duration="".2"" Fps=""40"">")
    sb.WriteLine(" <StyleAction AnimationTarget=""{0}""
    Attribute=""display"" Value=""none"" />", collapseButton.UniqueID)
    sb.WriteLine(" <StyleAction AnimationTarget=""{0}""
    Attribute=""display"" Value=""inline"" />", expandButton.UniqueID)
    sb.WriteLine(" <StyleAction AnimationTarget=""{0}""
    Attribute=""display"" Value=""none"" />", bodyPanel.UniqueID)
    sb.WriteLine(" </Parallel>")
    sb.WriteLine("</OnClick>")

    Return sb.ToString
    End Function

    Private Function GetExpandAnimationXml() As String
    Dim sb As New IO.StringWriter

    sb.WriteLine("<OnClick>")
    sb.WriteLine(" <Parallel Duration="".2"" Fps=""40"">")
    sb.WriteLine(" <StyleAction AnimationTarget=""{0}""
    Attribute=""display"" Value=""none"" />", expandButton.UniqueID)
    sb.WriteLine(" <StyleAction AnimationTarget=""{0}""
    Attribute=""display"" Value=""inline"" />", collapseButton.UniqueID)
    sb.WriteLine(" <StyleAction AnimationTarget=""{0}""
    Attribute=""display"" Value=""block"" />", bodyPanel.UniqueID)
    sb.WriteLine(" </Parallel>")
    sb.WriteLine("</OnClick>")

    Return sb.ToString
    End Function

    Public Sub Update()
    updatePanel.Update()
    End Sub

    Public Sub CollapsePanel()
    If IsCollapsible Then
    collapseButton.Style("display") = "none"
    expandButton.Style("display") = "inline"
    bodyPanel.Style("display") = "none"
    End If
    End Sub

    Public Sub OpenPanel()
    If IsCollapsible Then
    collapseButton.Style("display") = "inline"
    expandButton.Style("display") = "none"
    bodyPanel.Style("display") = "block"
    End If
    End Sub

    #End Region

    End Class

    Public Class CollapsingPanelDesigner
    Inherits PanelContainerDesigner

    Private panel As CollapsingPanel

    Public Overrides Sub Initialize(ByVal component As IComponent)
    MyBase.Initialize(component)
    panel = component
    End Sub

    Public Overrides ReadOnly Property FrameCaption() As String
    Get
    Return IIf(panel.Title Is Nothing Or panel.Title.Trim = "",
    "Collapsible Panel", panel.Title)
    End Get
    End Property
    End Class


    <ViewStateModeById()> _
    Public Class CollapsingPanelTemplateContainer
    Inherits WebControl
    Implements INamingContainer

    'Private _parent As CollapsingPanel

    'Public Sub New(ByVal Parent As CollapsingPanel)
    ' _parent = Parent
    'End Sub

    'Public ReadOnly Property CollapsingPanel() As CollapsingPanel
    ' Get
    ' Return _parent
    ' End Get
    'End Property

    End Class

    End Namespace
    George, Nov 13, 2009
    #1
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. =?Utf-8?B?QW1pbmU=?=

    Itemplate viewstate

    =?Utf-8?B?QW1pbmU=?=, Jan 17, 2005, in forum: ASP .Net
    Replies:
    1
    Views:
    2,831
    Karl Seguin
    Jan 17, 2005
  2. John Dalberg
    Replies:
    3
    Views:
    3,181
    =?Utf-8?B?RWx0b24gVw==?=
    Apr 29, 2005
  3. Jeff Rodriguez
    Replies:
    23
    Views:
    1,080
    David Schwartz
    Dec 9, 2003
  4. Replies:
    0
    Views:
    192
  5. Trevor Benedict R

    ViewState Does not Persist with Named DataGrid Item

    Trevor Benedict R, Sep 13, 2004, in forum: ASP .Net Datagrid Control
    Replies:
    2
    Views:
    167
    Trevor Benedict R
    Sep 14, 2004
Loading...

Share This Page