views:

4452

answers:

5

I have a GridView with a TemplateField with a checkbox. My goal is to capture the onclick event using autopostback and setting a database flag. My only problem is that the event fire's twice. The first time The Checkbox (In the sender parameter) holds the clicked value so I set it based on the click. The second time the sender parameter has a checkbox that is always checked=false. I am happy to entertain suggestions on other approached to solving this problem but my goal is to set a database flag based on the user checking a checkbox. I am targeting .NET Framework 2.0.

Here is the associated code:

<div style="margin-left : 1em;margin-right:1em;">
    <asp:GridView ID="RouteGridView" runat="server" AllowPaging="True" 
            AutoGenerateColumns="False" CellPadding="4" DataKeyNames="ROUTE_NUMBER" 
            ForeColor="#333333" GridLines="None" style="width:100%;" 
        onselectedindexchanged="RouteGridView_SelectedIndexChanged" 
        AllowSorting="True" onpageindexchanging="RouteGridView_PageIndexChanging" 
        onsorting="RouteGridView_Sorting" >
            <Columns>
<%-- Column one --%>
<asp:TemplateField HeaderText="Route" SortExpression="ROUTE_NUMBER">
    <ItemTemplate>
        <asp:LinkButton ID="HyperLink1" runat="server" CommandName="Select" CommandArgument='<%#Eval("ROUTE_NUMBER")%>'  
                            Text='<%# Eval("ROUTE_NUMBER") %>' ></asp:LinkButton>
    </ItemTemplate>
    <ItemStyle HorizontalAlign="Center" />
</asp:TemplateField>

<%-- Column 2 this is where the problem CheckBox is--%>
<asp:TemplateField HeaderText="Read?" 
    SortExpression="READ_FLAG">
    <ItemTemplate>
        <asp:CheckBox ID="CheckBox1" runat="server" 
            OnCheckedChanged="ChangeReadFlag"  
            AutoPostBack="true"
            Checked='<%# (string)DataBinder.Eval(Container.DataItem, "READ_FLAG") == "1" %>' Enabled='<%# isSelectedRow(Container)  %>' />
    </ItemTemplate>
    <ItemStyle HorizontalAlign="Center" />
</asp:TemplateField>

<%-- more columns --%
<%-- more columns --%>
</Columns>
</asp:GridView>

Here is the event handler from the code behind:

protected void ChangeReadFlag(object sender, EventArgs e)
{
    if (RouteGridView.SelectedIndex != -1)
    {
        CheckBox cb = ((CheckBox)sender);
        DataKey key = RouteGridView.SelectedDataKey;

        //... do stuff here ...
    }
}
A: 

You want to capture the even of the GridView; identify the command (sender) that is causing the postback, and then you can execute your DB update.

Victor
+1  A: 

Do you set the checked status of the checkbox to false at all in your page load event?

Chris Conway
This would be my bet.
Brian Rudolph
A: 

One of the reasons(there may be others) the problem comes is the event is registered twice.

Check your Code in the code behind, inside "InitializeComponent". This will cause the event to be registered twice and hence fire twice.

You need to remove it at one place to solve the issue.

rAm.

rAm
+1  A: 

There could be several reasons for such behavior. In my case it was that the event was being registered twice: one time automatically as a part of the checkbox definition
<asp:CheckBox ID="CheckBox1" runat="server" **OnCheckedChanged="ChangeReadFlag"** AutoPostBack="true" Checked='<%# (string)DataBinder.Eval(Container.DataItem, "READ_FLAG") == "1" %>' Enabled='<%# isSelectedRow(Container) %>' />

and the second time - an explicit registration somewhere in code, usually in OnInit method:
CheckBox1.CheckedChanged += new EventHandler(ChangeReadFlag);

In order to fix it, you should remove the second registration either from the code behind or from your control.

Lekim
A: 

Another potential problem is where your databinding is happening - I don't see a DataSource in your code-in-front, so I guess you're databinding in the code-behind.

If you are doing the databind on postback, and after the first onChange event has fired, it's quite likely that the databind event is reseting the checkbox's status, and so causing the event to fire again.

Zhaph - Ben Duguid