ASP.NET - 在Repeater中使用CheckBoxes

时间:2010-07-29 20:13:47

标签: asp.net checkbox postback repeater

我有点困惑。我有一个Repeater,它填充了一个Checkbox控件列表和Label控件。但似乎在ViewState中记住复选框的选中状态直到第一次回发之后才会记住。

场景:我的自定义复选框列表中有5个项目。我选择前3并提交表格。不再选择前3个。我选择第1,3和5项并再次提交。页面加载后,仍然会选择1,3和5。

这是我正在使用的测试页面的完整代码。我为VB道歉:-p

Imports System.Xml

Partial Public Class _Default
    Inherits System.Web.UI.Page

    Dim _roles As Repeater
    Dim _output As Literal

    Private Sub Page_Init(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Init
        _roles = New Repeater()
        _roles.ItemTemplate = New RolesListTemplate(ListItemType.Item)
        Me.Form.Controls.Add(_roles)

        Dim btn As New Button()
        btn.Text = "Save"
        btn.UseSubmitBehavior = True
        AddHandler btn.Command, AddressOf btnSave_OnCommand
        Me.Form.Controls.Add(btn)

        _output = New Literal
        Me.Form.Controls.Add(_output)
    End Sub

    Private Sub btnSave_OnCommand(ByVal sender As Object, ByVal e As CommandEventArgs)
        Dim roleData As String = GetXML(_roles)
        _output.Text = "<br>" & HttpUtility.HtmlEncode(roleData) & "<br>DONE"
    End Sub

    Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load

        If Not Page.IsPostBack Then
            Dim RoleData As New List(Of Role)

            RoleData.Add(New Role With {.selected = 0, .enabled_ind = 1, .role_id = 123, .role_description = "Role 123"})
            RoleData.Add(New Role With {.selected = 0, .enabled_ind = 1, .role_id = 345, .role_description = "Role 345"})
            RoleData.Add(New Role With {.selected = 0, .enabled_ind = 1, .role_id = 678, .role_description = "Role 678"})
            RoleData.Add(New Role With {.selected = 0, .enabled_ind = 1, .role_id = 6987, .role_description = "Role 6987"})
            RoleData.Add(New Role With {.selected = 0, .enabled_ind = 1, .role_id = 1122, .role_description = "Role 1122"})

            If RoleData IsNot Nothing Then
                If RoleData.Count > 0 Then
                    _roles.DataSource = RoleData
                    _roles.DataBind()
                    _roles.Visible = True
                Else
                    _roles.Visible = False
                End If
            End If
        End If

    End Sub

    Private Function GetXML(ByVal _cb_roles As Repeater) As String

        Dim settings As New XmlWriterSettings
        settings.CheckCharacters = True
        settings.CloseOutput = True
        settings.OmitXmlDeclaration = True

        Dim xw As XmlWriter
        Dim sb As New StringBuilder()
        xw = XmlWriter.Create(sb, settings)

        xw.WriteStartDocument()
        xw.WriteStartElement("roles")

        For Each row As RepeaterItem In _cb_roles.Items
            Dim pnl As Panel = TryCast(row.Controls.Item(0), Panel)
            Dim cb As CheckBox = TryCast(pnl.Controls.Item(0), CheckBox)
            Dim id As String = String.Empty
            Dim parts() As String = cb.ID.Split("_"c)
            id = cb.InputAttributes("role_id")
            xw.WriteStartElement("role")
            xw.WriteAttributeString("role_id", id)
            If cb.Checked Then
                xw.WriteAttributeString("selected", "1")
            Else
                xw.WriteAttributeString("selected", "0")
            End If
            xw.WriteEndElement()

        Next

        xw.WriteEndElement()
        xw.WriteEndDocument()
        xw.Close()

        Return sb.ToString
    End Function

    Public Class RolesListTemplate
        Implements ITemplate, INamingContainer

        Private _ltItemType As ListItemType
        Private _ctlParent As WebControl

        Sub New(ByVal pType As ListItemType)
            Try
                _ltItemType = pType
            Catch ex As Exception
                Throw ex
            End Try
        End Sub

        Public Sub InstantiateIn(ByVal container As System.Web.UI.Control) Implements System.Web.UI.ITemplate.InstantiateIn

            Select Case _ltItemType

                Case ListItemType.Header
                Case ListItemType.Item

                    Dim pnl As New Panel()

                    Dim cb As New CheckBox()
                    cb.AutoPostBack = True
                    cb.ID = "role_check"
                    AddHandler cb.DataBinding, AddressOf RolesListTemplate_DataBind
                    pnl.Controls.Add(cb)

                    Dim lbl As New Label()
                    lbl.ID = "role_lbl"
                    AddHandler lbl.DataBinding, AddressOf RolesListTemplate_DataBind
                    pnl.Controls.Add(lbl)

                    container.Controls.Add(pnl)

                Case ListItemType.AlternatingItem
                Case ListItemType.Footer

            End Select

        End Sub

        Private Sub RolesListTemplate_DataBind(ByVal sender As Object, ByVal e As System.EventArgs)

            Dim _sender As Control = DirectCast(sender, Control)
            Dim container As RepeaterItem = DirectCast(_sender.NamingContainer, RepeaterItem)

            Dim role As Role = TryCast(container.DataItem, Role)
            If role IsNot Nothing Then

                If role.selected OrElse role.enabled_ind Then
                    Select Case _sender.ID
                        Case "role_check"
                            Dim role_check As CheckBox = DirectCast(_sender, CheckBox)
                            role_check.Checked = role.selected
                            role_check.ID = "role_list_" & role.role_id.ToString()
                            role_check.InputAttributes("role_id") = role.role_id.ToString()

                        Case "role_lbl"
                            Dim role_lbl As Label = DirectCast(_sender, Label)
                            role_lbl.Text = role.role_description
                    End Select
                Else
                    container.Visible = False
                End If

            End If

        End Sub

    End Class

    Public Class Role
        Public enabled_ind As Boolean
        Public selected As Boolean
        Public role_id As Integer
        Public role_description As String
    End Class

End Class

1 个答案:

答案 0 :(得分:2)

这是一个非常常见的错误。您想在DataBind活动中致电Init,即使是回帖。