Waleed Manzoor
Waleed Manzoor

Reputation: 95

Get checkbox value in grid view instead of using foreach loop

I am using foreach loop to get value of checkbox from a grid view and update the records by geting the current user regID on checkbox CheckedChanged event.

In ASPX

   <Columns>
      <asp:TemplateField >
                            <ItemTemplate>
                                <asp:CheckBox ID="cbPaid" runat="server" AutoPostBack="true" OnCheckedChanged="cbPaid_CheckedChanged" Checked='<%# bool.Parse(Eval("status").ToString() == "Paid" ? "True": "False") %>' />
                            </ItemTemplate>
                        </asp:TemplateField>
                    </Columns>

And in aspx.cs

protected void cbPaid_CheckedChanged(object sender, EventArgs e)
{
    foreach (GridViewRow row in GdParticipants.Rows)
    {
        CheckBox cbPaid = (CheckBox)row.FindControl("cbPaid");

        if (cbPaid!=null && cbPaid.Checked == true)
        {
            string status = "Paid";
            int amount = Convert.ToInt32(ViewState["EventFee"]);
            DateTime date = DateTime.Now;
            string user = Session["user_id"].ToString();
            string regID = row.Cells[2].Text;

            string type = "Deposit";
            string account = "Participation";
            int balance = BAL.fetch_availableBalance();
            int total_balance = amount + balance;
            string detail = "Participant: "+regID+" fee has been Recieved";
            BAL.updateParticipants(regID, status, amount, user, date);
            BAL.saveBudgetTracking(type,account,amount,0,total_balance,detail,date);

        }
    }
    Response.Redirect("~/show_members.aspx");
}

The problem with this approach is whenever a new user updated a new record by checking a check box it will loop through the whole records and update the current change all over the previous records.

Anyone please guide me how can I get only the current regID from the row on which the checkbox was being checked and the checkbox value on checkbox-CheckedChanged event, instead of a loop?

Upvotes: 1

Views: 1798

Answers (3)

Win
Win

Reputation: 62260

You can search sibling controls by Parent.

I personally like using Label control so that I can call FindControl, because if you reorder columns, row.Cells[2].Text will crash the application at run-time.

<asp:GridView ID="GridView1" runat="server">
    <Columns>
        <asp:TemplateField>
            <ItemTemplate>
                <asp:Label runat="server"
                    ID="RegIDLabel"
                    Text='<%# Eval("RegID") %>' />
            </ItemTemplate>
        </asp:TemplateField>
        <asp:TemplateField>
            <ItemTemplate>
                <asp:CheckBox ID="cbPaid" runat="server"
                    AutoPostBack="true"
                    OnCheckedChanged="cbPaid_CheckedChanged"
                    Checked='<%# bool.Parse(Eval("status").ToString() == "Paid" ? "True": "False") %>' />
            </ItemTemplate>
        </asp:TemplateField>
    </Columns>
</asp:GridView>

Code Behind

public partial class Default : System.Web.UI.Page
{
    protected void Page_Load(object sender, EventArgs e)
    {
        if (!IsPostBack)
        {
            GridView1.DataSource = new List<Item>
            {
                new Item {RegID = "1", Status = "Paid"},
                new Item {RegID = "2", Status = "Other"},
                new Item {RegID = "3", Status = "Paid"},
            };
            GridView1.DataBind();
        }
    }

    protected void cbPaid_CheckedChanged(object sender, EventArgs e)
    {
        var cbPaid = sender as CheckBox;
        var cell = cbPaid.Parent as DataControlFieldCell;
        var row = cell.Parent as GridViewRow;
        var regIDLabel = row.FindControl("RegIDLabel") as Label;
        var regId = regIDLabel.Text;

        if (cbPaid.Checked)
        {
            // Do something
        }
    }
}

Upvotes: 0

Mathieu
Mathieu

Reputation: 526

The sender is the CheckBox object and it's level 2 partent is the GridViewRow :

protected void cbPaid_CheckedChanged(object sender, EventArgs e)
{
    CheckBox cbPaid = sender as CheckBox;

    if (cbPaid != null && cbPaid.Parent != null)
    {
        GridViewRow row = cbPaid.Parent.Parent as GridViewRow;

        if (row != null )
        {
            string status = "Paid";
            int amount = Convert.ToInt32(ViewState["EventFee"]);
            DateTime date = DateTime.Now;
            string user = Session["user_id"].ToString();
            string regID = row.Cells[2].Text;

            string type = "Deposit";
            string account = "Participation";
            int balance = BAL.fetch_availableBalance();
            int total_balance = amount + balance;
            string detail = "Participant: " + regID + " fee has been Recieved";
            BAL.updateParticipants(regID, status, amount, user, date);
            BAL.saveBudgetTracking(type, account, amount, 0, total_balance, detail, date);
            Response.Redirect("~/show_members.aspx");
        }
    }

}

Upvotes: 1

DevCod
DevCod

Reputation: 300

Use the below code, it will avoid looping thru the Grid.

protected void cbPaid_CheckedChanged(object sender, EventArgs e)
{
      int selRowIndex = ((GridViewRow)(((CheckBox)sender).Parent.Parent)).RowIndex;
      CheckBox cb = (CheckBox)GdParticipants.Rows[selRowIndex].FindControl("cbPaid");
      if (cb.Checked)
      {
             //respective cell's value
            string regID = GdParticipants.Rows[selRowIndex].Cells[2].Text;

            //Perform your rest of the logic
       }
}

Upvotes: 0

Related Questions