1

I have a pretty standard GridView. This includes a TemplateField with a checkbox. I set the checkboxes to checked/unchecked based on values in a database. The checkboxes have a CheckedChanged event. After the page has loaded the first time I click a checkbox that is checked. The CheckedChanged event fires, but the CheckBox always has Checked = true. Any subsequent clicks on checkboxes, and the information in the event is correct.

What is causing this?

.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>

Code behind

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 {
    }
}
0

1 Answer 1

1

Why do you use RowCreated instead of RowDataBound? RowCreated is always triggered, so on each and every postback, before the events are triggered. So maybe it is fixed if you move that code to RowDataBound which is only called after 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;
    }
}

You can access the datasource in RowDataBound. If you want to evaluate a field in the record you have to cast e.Row.DataItem to the actual type(f.e. a DataRowView).

Sign up to request clarification or add additional context in comments.

4 Comments

I updated the comment in CheckedChanged to avoid confusion.
I changed to RowDataBound instead of RowCreated, and now it works as it should. Any idea why RowCreated introduced this strange behaviour? I had used debugging to see if RowCreated was called again to overwrite the value, but RowCreated was only called once (when the GridView was rendered, then never again).
@GTHvidsten: because RowCreated must be called on every postback as first step to create all controls. All things that are persisted in viewstate and that depend on the datasource belong into RowDataBound. When the Checked state is changed in RowCreated at MyCheckBox.Checked = isSomethingMarkedInDatabase;, then this happens before the CheckedChanged-event was triggered. That causes your issue. RowDataBound fixes this issue because it is not triggered on postback (unless you don't call DataBind).
How is MyCheckBox.Checked = isSomethingMarkedInDatabase called? I tried setting a breakpoint there when debugging, and that line was not called when I checked/unchecked a checkbox, only one time when the page was first loaded.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.