带有 CheckBox 的 GridView,CheckedChanged 第一次始终为真

GridView with CheckBox, CheckedChanged always true the first time

我有一个非常标准的 GridView。这包括带有复选框的 TemplateField。我根据数据库中的值将复选框设置为 checked/unchecked。 复选框有一个 CheckedChanged 事件。第一次加载页面后,我单击已选中的复选框。 CheckedChanged 事件触发,但 CheckBox 始终具有 Checked = true。任何后续的复选框点击,以及事件中的信息都是正确的。

这是什么原因造成的?

.aspx

<asp:UpdatePanel runat="server">
    <ContentTemplate>
        <asp:GridView ID="MyGV" runat="server" DataKeyNames="Id" OnRowCreated="MyGV_RowCreated" AutoGenerateColumns="false">
            <Columns>
                <asp:TemplateField HeaderText="My checkboxes">
                    <ItemTemplate>
                        <asp:CheckBox ID="MyCheckBox" runat="server" OnCheckedChanged="MyCheckBox_CheckedChanged" AutoPostBack="true" />
                    </ItemTemplate>
                </asp:TemplateField>
            </Columns>
        </asp:GridView>
    </ContentTemplate>
</asp:UpdatePanel>

代码隐藏

protected void Page_Load(object sender, EventArgs e) {
    if (!IsPostBack) {
        MyGV.DataSource = myfetcheddata;
        MyGV.DataBind();
    }
}

protected void MyGV_RowCreated(object sender, GridViewRowEventArgs e) {
    CheckBox MyCheckBox = (CheckBox)e.Row.FindControl("MyCheckBox");
    if (isSomethingMarkedInDatabase) {
        MyCheckBox.Checked = true;
    }
}

protected void MyCheckBox_CheckedChanged(object sender, EventArgs e) {
    CheckBox MyCheckBox = (CheckBox)sender;
    if (MyCheckBox.Checked) {
        // This is always run the first time a checkbox is clicked, whether or not it was checked or not in the first place. Any subsequent clicks on checkboxes has correct behaviour here.
    } else {
    }
}

为什么使用 RowCreated 而不是 RowDataBoundRowCreated 总是被触发,所以在每次回发时,在事件被触发之前。因此,如果您将该代码移动到 RowDataBound ,它只在 grid.DataBind().

之后调用,也许它是固定的
protected void MyGV_RowDataBound(object sender, GridViewRowEventArgs e) {
    if (row.RowType == DataControlRowType.DataRow){
        CheckBox MyCheckBox = (CheckBox)e.Row.FindControl("MyCheckBox");
        MyCheckBox.Checked = isSomethingMarkedInDatabase;
    }
}

您可以访问 RowDataBound 中的数据源。如果你想评估记录中的一个字段,你必须将 e.Row.DataItem 转换为实际类型(f.e.a DataRowView)。