2016-08-01 31 views
3

Ich habe eine GridView mit einer Checkbox-Spalte. Wenn Sie auf eine Schaltfläche klicken, sollten alle Zeilen mit dem aktivierten Kontrollkästchen entfernt werden. Ich bin irgendwie auf eine seltsame und hacky Lösung gestoßen, und ich habe keine Idee, warum es funktioniert. Ich habe bereits verwandte SO-Fragen bereits durchsucht.ASP.NET CheckBox nicht auf Postback ohne seltsamen Hack überprüft

Verwandte Code:

Protected Sub Page_Init(ByVal sender As Object, ByVal e As EventArgs) Handles Me.Init 
    ' I have no idea why this is needed for the checkboxes to work... 
    Dim x = imageGridView.Rows 
End Sub 


Protected Sub RemoveButton_Click(ByVal sender As Object, ByVal e As EventArgs) Handles removeButton.Click 

    For Each row As GridViewRow In imageGridView.Rows 
     Dim selectCheckBox As CheckBox = DirectCast(row.Cells(0).FindControl("selectCheckBox"), CheckBox) 
     If selectCheckBox.Checked Then 
      Dim fileName As String = row.Cells(1).Text 
      ImageList.Remove(ImageList.FindLast(Function(r) r.FileName = fileName)) 
     End If 
    Next 
    imageGridView.DataSource = ImageList 
    imageGridView.DataBind() 
End Sub 

Aspx:

<asp:GridView ID="imageGridView" runat="server"> 
    <Columns> 
     <asp:TemplateField> 
      <ItemTemplate> 
       <asp:CheckBox ID="selectCheckBox" runat="server" /> 
      </ItemTemplate> 
     </asp:TemplateField> 
    </Columns> 
</asp:GridView> 

Die Linie Dim x = imageGridView.Rows wird für die Zeilen erforderlich entfernt werden. Ich fand das, nachdem ich meinen RemoveButton_Click Code in dem Page_Init Sub versucht hatte und dann Code entfernte, bis es nicht mehr funktionierte. Dim x = imageGridView ist nicht genug, und es funktioniert nicht, um das Gleiche in Page_Load zu tun.

Meine Kontrollkästchen sind nie deaktiviert.

Also, einfach ausgedrückt, warum ist es für mich notwendig imageGridView.Rows im Page_Init für meinen Code zu verweisen zu arbeiten?

+0

Machst du einen vollständigen Postback oder verwenden Update-Panels? –

+0

Ich habe ein 'UpdatePanel', das den' addButton' auslöst, aber das Gitter ist nicht im Panel enthalten. – mbomb007

Antwort

1

Das ist ein interessantes Verhalten. Ich reproduzieren das Problem, wenn ich die Daten an die GridView in Page_Load auf jedem Postback binde. In dieser Situation verlieren die Kontrollkästchen ihren Auswahlstatus beim Postback, aber nicht, wenn wir auf imageGridView.Rows in Page_Init verweisen, wie Sie beobachtet haben.

Die Lösung ist, die Daten innerhalb eines If Not IsPostBack Bedingungsblock zu binden:

Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load 
    If Not IsPostBack Then 
     imageGridView.DataSource = ImageList 
     imageGridView.DataBind() 
    End If 
End Sub 

In diesem Fall jedoch wir nicht in imageGridView.RowsPage_Init beziehen. Dadurch verlieren die Kontrollkästchen ihren Auswahlstatus (!?!).

Aus dem Quellcode des Gridview (unter der Annahme, dass this source zuverlässig ist), merke ich, dass die Rows Sammlung Zugriff auf einen Anruf zu EnsureChildControls auslöst, die dann CreateChildControls aufrufen. Ich war nicht in der Lage, in den .NET-Code zu gehen, um zu sehen, was zu diesem Zeitpunkt passiert. Der Aufruf dieser Methoden im Ereignishandler Page_Init kann früher als erwartet in life cycle of the GridView erfolgen.

Übrigens löst auch der Zugriff auf die Eigenschaften HeaderRow und FooterRow einen Aufruf an EnsureChildControls aus und wirkt sich auch auf den Auswahlstatus der Kontrollkästchen aus.

+0

Ich dachte, ich müsste die Daten jeden Postback neu binden oder es würde nicht übertragen, aber anscheinend nicht. Vielen Dank! – mbomb007