0

In my gridview, I inserted a column that contains a checkbox in the header:

<asp:TemplateField ItemStyle-HorizontalAlign="Center">
    <HeaderTemplate>
        <asp:CheckBox ID="chkBxHeader" Text="<br />Select"
            AutoPostBack="true"
            OnCheckedChanged="chkBxHeader1_CheckedChanged" 
            runat="server" />
    </HeaderTemplate>
    <ItemTemplate>
        <div>
            <br />
            <asp:CheckBox ID="chkRow" runat="server" />
            <asp:ImageButton ID="btnchkRow"
                ImageUrl="/img/checkbox_closed.gif"
                runat="server" />
        </div>
    </ItemTemplate>
</asp:TemplateField>

Selecting this checkbox will perform the following procedure chkBxHeader1_CheckedChanged which follows the validation of the gridview rows:

try
{
    CheckBox chkBxHeader = (CheckBox)sender;
    bool isvalid = false;

    foreach (GridViewRow row in gvProducts.Rows)
    {
        if (row.RowType == DataControlRowType.DataRow)
        {
            if (!(row.FindControl("chkRow") as CheckBox).Checked)
            {
                Page.ClientScript.RegisterStartupScript(this.GetType(), "Alert",
                    "alert('KO');", true);
                chkBxHeader.Checked = false;
                isvalid = false;
                break;
            }
            else
            {
                chkBxHeader.Checked = true;
                chkBxHeader.Enabled = false;
                isvalid = true;
            }
        }
    }

    // Process only if valid.
    if (isvalid)
    {
        Page.ClientScript.RegisterStartupScript(this.GetType(), "Alert",
            "alert('OK');", true);
    }
}
catch (Exception ex)
{
    Console.WriteLine("Skipped exception! " + ex);
}

If the procedure is successful I disable the checkbox in the column header.

My problem is when I return to the gridview when I have closed the browser or changed the web page even though all the checkboxes are selected the checkbox in the column header is always visible and selectable.

In this case the checkbox in the column header must be hidden or inhibited.

I have tried this in GridView1_RowDataBound, without success:

protected void GridView1_RowDataBound(object sender, GridViewRowEventArgs e)
{     
    try
    {
        if (e.Row.RowType == DataControlRowType.DataRow ||
            e.Row.RowType == DataControlRowType.Header)
        {
            int counter = 0;

            foreach (GridViewRow row in GridView1.Rows)
            {
                CheckBox chkRow = (row.Cells[0].FindControl("chkRow") as CheckBox);

                if (chkRow.Checked)
                {
                    counter++;
                }
            }

            if (counter == 9)
            {
                CheckBox chkBxHeader = (CheckBox)e.Row.FindControl("chkBxHeader");
                Response.Write(counter + "<br />");
                chkBxHeader.Visible = false;
            }
        }
    }
    catch (Exception ex)
    {
        Console.WriteLine("Skipped exception! " + ex);
    }
}

Update 2025/03/25

if (ds.Tables[0].Rows.Count > 0)
{
    dt = ds.Tables[0];

    CheckBox chkHeader = (CheckBox)GridView1.HeaderRow.FindControl("chkBxHeader");

    // if 9 or more rows are checked, then disable heading check box
    int ckCount = 0;
    foreach (GridViewRow gRow in GridView1.Rows)
    {
        CheckBox chkRow = (CheckBox)gRow.FindControl("chkRow");
        if (chkRow.Checked)
            ckCount++;
    }
    if (ckCount >= 9)
    {
        chkHeader.Enabled = false;
    }
    else
    {
        chkHeader.Enabled = true;
    }
}

Error

Server Error in '/aspnet' Application.
Object reference not set to an instance of an object.
Description: An unhandled exception occurred during the execution of the current web request. Please review the stack trace for more information about the error and where it originated in the code.

Exception Details: System.NullReferenceException: Object reference not set to an instance of an object.

Source Error:


Line 1102:                        dt = ds.Tables[0];
Line 1103:
Line 1104:                        CheckBox chkHeader = (CheckBox)GridView1.HeaderRow.FindControl("chkBxHeader");
Line 1105:                        // if 9 or more rows are checked, then disable heading check box
Line 1106: 

Update 2025/03/27 Solved

int counter = 0;
protected void GridView1_RowDataBound(object sender, GridViewRowEventArgs e)
{
    if (e.Row.RowType == DataControlRowType.DataRow)
    {
        CheckBox chkRow = (e.Row.FindControl("chkRow") as CheckBox);
        if (chkRow.Checked)
        {
            counter++;
        }
    }
    if (counter == 9)
    {
        CheckBox chkBxHeader = GridView1.HeaderRow.FindControl("chkBxHeader") as CheckBox;
        chkBxHeader.Checked = true;
        chkBxHeader.Enabled = false;
    }
}   
5
  • if (counter == 9) so, only if the results count is 9 will it hide it? Commented Mar 25 at 14:33
  • @RyanWilson Exactly, only if the results count is 9 I need hide the checkbox in the header, thanks Commented Mar 25 at 14:39
  • don't use row databound, as that fires for each and every row. You want a simple count of checked rows - do this AFTER you bind the GV. See my sample code below. Commented Mar 25 at 18:46
  • @AlbertD.Kallal Thank you for suggestion. Please see Update 2025/03/25 on the question Commented Mar 25 at 19:17
  • No loop as you have looks just fine. Commented Mar 27 at 21:45

1 Answer 1

0

Well, it makes no sense to use the row data bound event here. The row data bound event fires for EACH row, and then in your row data bound event, you THEN are running a full loop over all rows. That means for 20 rows, you going to run the loop over 20 rows, for 20 rows!

That will result in 20 x 20 times operations (400 operations).

So, I would suggest you simple bind the data, and then test/count the checked rows, and enable the header based on this simple count.

Hence, this code:

    protected void Page_Load(object sender, EventArgs e)
    {
        if (!IsPostBack)
            LoadData();
    }

    void LoadData()
    {
        string strSQL =
            @"SELECT * FROM tblhotelsA
            ORDER BY HotelName";

        GridView1.DataSource = General.MyRst(strSQL);
        GridView1.DataBind();

        CheckBox chkHeader = (CheckBox)GridView1.HeaderRow.FindControl("chkBxHeader");
        // if 9 or more rows are checked, then disable heading check box
        int ckCount = 0;
        foreach (GridViewRow gRow in GridView1.Rows)
        {
            CheckBox chkRow = (CheckBox)gRow.FindControl("chkRow");
            if (chkRow.Checked)
                ckCount++;
        }
        if (ckCount >= 9)
            chkHeader.Enabled = false;

    }

Hence, you can do your loop/testing after you bind the GridView, and based on the count of check boxes, you can enable/disable the header check box with the above code.

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

Comments

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.