ASP.NET флажок не установлен на postback без странного взлома


Меня GridView с колонкой флажка. При нажатии на кнопку все строки с установленным флажком должны быть удалены. Я каким-то образом наткнулся на странное и банальное решение, и я понятия не имею, почему оно работает. Я уже просматривал связанные с этим вопросы.

Соответствующий код:

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>

Строка Dim x = imageGridView.Rows необходима для удаления строк. Я нашел это после того, как попробовал мой RemoveButton_Click код в Page_Init sub, а затем удалил код, пока он не перестал работать больше не. Dim x = imageGridView недостаточно, и это не работает, чтобы сделать то же самое в Page_Load.

Мои флажки никогда не отключаются.

Итак, проще говоря, почему мне необходимо ссылаться на imageGridView.Rows в Page_Init, чтобы мой код работал?
1 3

1 ответ:

Это интересное поведение. Я воспроизвожу проблему, если я привязываю данные к GridView в Page_Load на каждой обратной передаче. В этой ситуации флажки теряют свое состояние выбора при обратной передаче, но не тогда, когда мы ссылаемся на imageGridView.Rows в Page_Init, Как вы заметили.

Решение состоит в том, чтобы связать данные внутри условного блока If Not IsPostBack:

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
Однако в этом случае мы не должны ссылаться на imageGridView.Rows в Page_Init. Это приводит к тому, что флажки теряют свое состояние выбора (!?!).

Из исходного кода GridView (предполагая, что этот источник надежен), я замечаю, что доступ к коллекции Rows вызывает вызов EnsureChildControls, который затем вызывает CreateChildControls. Я не смог войти в .NET-код, чтобы увидеть, что происходит в этот момент. Вызов этих методов в обработчике событий Page_Init может произойти раньше, чем ожидалось в жизненном цикле GridView.

Кстати, доступ к свойствам HeaderRow и FooterRow также инициирует вызов EnsureChildControls, и оказывает такое же влияние на состояние выбора флажков.