2010-07-29 4 views
1

Я немного запутался. У меня есть Repeater, который заполняет список элементов управления Checkbox и элементов управления Label. Но не похоже, что проверенное состояние флажков запоминается в ViewState до ПОСЛЕ первой обратной передачи.ASP.NET - Использование CheckBoxes в ретрансляторе

Сценарий: У меня есть 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

Не нужно извиняться за VB. – ChaosPandion

+0

Предполагалось, что он будет направлен на то, что код VB выглядит как нежелательный элемент в подсветке синтаксиса. –

+0

Что он делает. :) – ChaosPandion

ответ

2

Это очень распространенная ошибка. Вы хотите позвонить DataBind в мероприятие Init, даже для почтовых сообщений.

+0

Aah ... так, я должен сделать мои вызовы базы данных при загрузке страницы? Это страница с низким трафиком, поэтому влияние базы данных минимально, но для меня это кажется неаккуратным. –

+0

@Wes - Несчастливо, но Web Forms всегда стремилась к быстрому развитию эффективности. – ChaosPandion

+0

Динамические элементы управления немного неряшливы. Скорее всего, вы можете перестроить свой код, чтобы привязать данные к репитеру на странице, вместо того, чтобы добавить ретранслятор в контейнер через код. – ScottE

Смежные вопросы