views:

153

answers:

0

Hi all,

I have a custom Panel control which works like a regular Panel, but adds a heading to the top. The code for this panel is as follows :

Public Class GInfoPanel
    Inherits System.Web.UI.WebControls.Panel

    Protected WithEvents lblHeader As New Label()
    Protected WithEvents innerDiv As New HtmlGenericControl("div")

    Public Property HeaderText() As String
        Get
            Return lblHeader.Text
        End Get
        Set(ByVal value As String)
            lblHeader.Text = value
        End Set
    End Property

    Private Sub GInfoPanel_Init( _
        ByVal sender As Object, ByVal e As System.EventArgs) _
        Handles Me.Init

        innerDiv.Attributes("class") = "panel"
        lblHeader.CssClass = "panelHeader"

        'I think it's the copying of the controls which prevents the '
        'DetailsView maintaining it's CurrentMode property.'
        For i As Integer = Controls.Count - 1 To 0 Step -1
            'Add at 0 to maintain control order.'
            innerDiv.Controls.AddAt(0, Controls(i))
        Next

        Controls.AddAt(0, lblHeader)
        Controls.AddAt(1, innerDiv)
    End Sub
End Class

If I use a DetailsView control within this panel, I have the following problem. Clicking "Edit" will change it into Edit mode, but clicking Update or Cancel will have no effect, and it will remain in edit mode.

The ASP code is :

<uc1:GInfoPanel runat="server" HeaderText="Test Panel">
    <asp:DetailsView ID="dv" runat="server" 
        AutoGenerateEditButton="true" 
        AutoGenerateRows="True">
    </asp:DetailsView>
</uc1:GInfoPanel>

The code-behind is as follows :

    Private Sub BindPerson()
        'I use a BusinessObject class here, but I've replaced it with a 
        'standard .NET class for clarity.
        Dim oList As New List(Of Point)
        oList.Add(New Point(1, 3))

        dv.DataSource = oList
        dv.DataBind()
    End Sub

    Private Sub dv_ModeChanging( _
        ByVal sender As Object, ByVal e As System.Web.UI.WebControls.DetailsViewModeEventArgs) _
        Handles dv.ModeChanging

        'When the DetailsView is inside a GPanel, 
        'dv.CurrentMode is always Edit here. 
        If e.CancelingEdit Then
            dv.ChangeMode(DetailsViewMode.ReadOnly)
        Else
            dv.ChangeMode(e.NewMode)
        End If
        dv.ChangeMode(e.NewMode)
        BindPerson()
    End Sub

    Private Sub dv_ItemUpdating( _
        ByVal sender As Object, ByVal e As System.Web.UI.WebControls.DetailsViewUpdateEventArgs) _
        Handles dv.ItemUpdating

        'Not shown - update code.
        dv.ChangeMode(DetailsViewMode.ReadOnly)
        BindPerson()
    End Sub

One thing I've noticed, as I mention in the comments, is that when the Mode is changing it is always changing to Edit when inside the GPanel, which can't be right! I'm sure the problem is to do with the copying of the controls inside the GPanel - is there a better way to do this?

EDIT: Just thinking about this - is the control unable to maintain it's viewstate because it now has a new naming container? If so, how might I go about re-writing the GPanel to support this?

EDIT2: I fixed the problem by moving the GPanel control copying code into the Page_Load, rather than Page_Init. I'm obviously missing a piece of understanding here!

Cheers,

RB.