views:

533

answers:

3

I have created a gridview with a column of checkboxes. I want the user to select the checkboxes, click the register button (outside the gridview), and have a title from the selected row displayed. From what I've read I should put the checkbox check in the button click event. I have done so, but apparently the only time it enters that event is at page load and right before the page loads, all the selected checkboxes are wiped. Therefore, my check for a selected checkbox never comes out true. Is there an event that would a better time to run this check, or perhaps a way to hold these values through the page load? The following isn't all my code, just the effected portions.

    protected void regButton_Click(Object sender, EventArgs e)
    {
        StringBuilder regClasses = new StringBuilder();
        for (int i = 0; i < SQLQueryClassListings.Rows.Count; i++)
        {
            //Response.Write(SQLQueryClassListings.Rows[i].Cells[0].Text + " checkbox check ");
            GridViewRow checkRow = SQLQueryClassListings.Rows[i];
            bool reg = ((CheckBox)(checkRow.FindControl("RowCheckBox"))).Checked;
            if (reg)
            {
                regClasses.Append(SQLQueryClassListings.Rows[i].Cells[0].Text + " ");
            }
        }
        Response.Write(regClasses);
    }

<asp:GridView ID="SQLQueryClassListings" AutoGenerateColumns="false" runat="server" 
        BorderWidth="1px" BackColor="White" CellPadding="5" BorderColor="Black" RowStyle-BorderColor = "Black"
        HeaderStyle-BackColor="#0D69F2" HeaderStyle-ForeColor="White" AlternatingRowStyle-BackColor="#E8E8E8" HeaderStyle-BorderColor="Black" GridLines="Both">
        <Columns>
            <asp:BoundField HeaderText="Classes" DataField="LeafName" HeaderStyle-HorizontalAlign="Left" ItemStyle-Width="250" 
                ItemStyle-BorderColor="#ADADAD" HeaderStyle-BorderColor ="Black"/>
            <asp:BoundField HeaderText="Teacher" DataField="TeacherName" HeaderStyle-HorizontalAlign="Left" ItemStyle-Width="200" 
                ItemStyle-BorderColor="#ADADAD" HeaderStyle-BorderColor ="Black"/>
            <asp:BoundField HeaderText="Available" DataField="SemesterEnds" HeaderStyle-HorizontalAlign="Center"  
                ItemStyle-HorizontalAlign ="Center" ItemStyle-Width="150" ItemStyle-BorderColor="#ADADAD" HeaderStyle-BorderColor ="Black"/>
            <asp:HyperLinkField HeaderText="Course Description & Career Tracks" DataNavigateUrlFields="ApplicableTracks" 
                Text="See Description" HeaderStyle-HorizontalAlign="Center" ItemStyle-HorizontalAlign ="Center" ItemStyle-BorderColor="#ADADAD" HeaderStyle-BorderColor ="Black"/>
            <asp:TemplateField HeaderText="Register" HeaderStyle-BorderColor="Black" ItemStyle-BorderColor = "#ADADAD" ItemStyle-HorizontalAlign="Center">
                <ItemTemplate>
                    <asp:CheckBox runat="server" ID="RowCheckBox"/>
                </ItemTemplate>
            </asp:TemplateField>
        </Columns>
    </asp:GridView>
    <p>
    <asp:Button ID="Button1" runat="server" Text="Register" OnClientClick="return confirm('You have sucessfully registered!')"
        OnClick="regButton_Click" />
+1  A: 

You need to get on the ItemDataBound event of the GridView control, find the CheckBox by ID, and do whatever you need.

Laymonite
..and you can do whatever you like!
Chris Ballance
A: 

You must read the checkboxes from the GridView. So this code will bring back the IDs of the rows checked. It will give you the idea and then you can change it for what you need.

protected string getCheckedIds(GridView gv)
{
    StringBuilder sb = new StringBuilder();

    foreach (GridViewRow gvr in gv.Rows)
    {
        if (!gvrIsChecked(gvr))   // see below for this method
            continue;

        if (sb.Length > 0)
            sb.Append(",");

         sb.Append(gv.DataKeys[gvr.DataItemIndex].Value);

    }

    return sb.ToString();

}


protected bool gvrIsChecked(GridViewRow gvr)
{
    // The location of your checkbox may be different.
    object cb = gvr.Cells[0].Controls[gvr.Cells[0].Controls.Count - 2];

    if (cb.GetType() != typeof(CheckBox))
        return false;    

    if (!((CheckBox)cb).Checked)
        return false;

    return true;
}
JBrooks
A: 

It's hard to know for sure without seeing more of your code, but it sounds like your page is re-binding the GridView on postbacks (such as your regButton_Click event). So it rebuilds the GridView every time the page loads - even after your user clicks the register button.

If that is the case, you can fix this by changing the code you use to bind your GridView like this:

if (!this.IsPostback) {
    SQLQueryClassListings.DataBind();
}

(This presumes that you have ViewState enabled for the page (or at least the GridView). There are other mechanisms you can use to communicate the client's state (such as checkbox selections) to the server, but ViewState (for all its faults) is the default tool for doign so in ASP.NET.)

A consequence is that the data shown in the GridView won't be completely up-to-date, but if you can tolerate that, this is a simple way to accomplish what you want.

Jeff Sternal
My hero! It works perfectly now. I'll never make this mistake again.
VengefulSakhmet
My pleasure. :) But it wasn't exactly a mistake! There are circumstances in which you will want to rebind on every postback (when you absolutely need up-to-the-minute data, for example). But in those cases, you'll need to use another method of communicating the user's selections to the server (like storing the ids in properties on your page backed by ViewState, or using hidden input controls on your forms).
Jeff Sternal