mbomb007 mbomb007 - 1 year ago 86
Vb.net Question

ASP.NET CheckBox not checked on postback without weird hack

I have a

with a checkbox column. On clicking a button, all rows with the checkbox checked should be removed. I somehow stumbled upon a strange and hacky solution, and I have no idea why it works. I already searched through related SO questions already.

Related 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
imageGridView.DataSource = ImageList
End Sub


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

The line
Dim x = imageGridView.Rows
is needed for the rows to be removed. I found this after trying my
code in the
sub, then removing code until it didn't work anymore.
Dim x = imageGridView
is not enough, and it doesn't work to do the same thing in

My checkboxes are never disabled.

So, simply put, why is it necessary for me to reference
in the
for my code to work?

Answer Source

That is an interesting behavior. I reproduce the problem if I bind the data to the GridView in Page_Load on every postback. In that situation, the check boxes lose their selection state on postback, but not if we refer to imageGridView.Rows in Page_Init, as you observed.

The solution is to bind the data inside an If Not IsPostBack conditional block:

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

In that case, however, we must NOT refer to imageGridView.Rows in Page_Init. Doing so causes the check boxes to lose their selection state (!?!).

From the source code of the GridView (assuming that this source is reliable), I notice that accessing the Rows collection triggers a call to EnsureChildControls which then calls CreateChildControls. I haven't been able to step into the .NET code to see what happens at that point. Calling these methods in the Page_Init event handler may come earlier than expected in the life cycle of the GridView.

By the way, accessing the HeaderRow and the FooterRow properties also triggers a call to EnsureChildControls, and has the same effect on the selection status of the check boxes.