Zath
Zath

Reputation: 557

Gridview find control in dynamic header row

This may have to do with the page life cycle but just can't seem to get it working, even after finding every post out there on the subject.

In a gridview, a new header row is created with a control:

protected void gvNotes_RowCreated(object sender, GridViewRowEventArgs e)
{
    if (e.Row.RowType == DataControlRowType.Header)
    {
        GridView HeaderGrid = (GridView)sender;
        GridViewRow HeaderGridRow = new GridViewRow(0, 0, DataControlRowType.Header, DataControlRowState.Insert);
        TableCell HeaderCell = new TableCell();

        CheckBox chk = new CheckBox();
        chk.Text = "Show Admin Columns";            
        chk.ID = "chk";
        chk.AutoPostBack = true;            
        chk.CheckedChanged += new EventHandler(this.chkShowAminColumns_CheckedChanged);

        HeaderCell.Controls.Add(chk);                   
        HeaderCell.ColumnSpan = gvNotes.Columns.Count;
        HeaderGridRow.Cells.Add(HeaderCell);
        gvNotes.Controls[0].Controls.AddAt(0, HeaderGridRow);
    }
}

Trying to find this new control is giving me a little trouble:

public void bindNotesGrid()
{
    DataTable dt = BLL.NotesBLL.GetNotes();
    gvNotes.DataSource = dt;
    gvNotes.DataBind();         


    if (dt.Rows.Count > 0)
    {
        //never finds the control
        foreach (Control c in gvNotes.HeaderRow.Controls)
        {
            if (c is CheckBox)
            {
                string value = ((CheckBox)c).Text;
            }
        }

        //never finds the control
        //int current = 0;
        //int headerCount = gvNotes.HeaderRow.Cells.Count;

        //for (current = 0; current < headerCount; current++)
        //{
        //    CheckBox chk2 = (CheckBox)gvNotes.HeaderRow.Cells[current].FindControl("chk");               
        //}

        //returns null
        CheckBox chk = (CheckBox)gvNotes.HeaderRow.FindControl("chk");

    }
}

All the findcontrol attempts return the checkbox as null. What am I not seeing here?

Thanks!

Upvotes: 0

Views: 1737

Answers (2)

Sharique Hussain Ansari
Sharique Hussain Ansari

Reputation: 1456

To find the control try this:-

foreach (Control c in gvNotes.Controls[0].Controls[0].Controls)
        {
            CheckBox chk = (CheckBox)c.FindControl("chk");
        }

gvNotes.Controls[0].Controls -> System.Web.UI.WebControls.Table.RowControlCollection

gvNotes.Controls[0].Controls[0].Controls -> System.Web.UI.WebControls.TableRow.CellControlCollection

as first you added TableRow and then TableCell

Hop this will help

Upvotes: 0

fnostro
fnostro

Reputation: 4591

The header row is generated by the GridView control based on your data source. It is not actually a member of your dataset but is dynamically built based on the contents of the data set.

Consider this code:

    int HeaderRowCount = -5;  // initialized to a wrong starting point

    protected void GridView1_DataBinding( object sender, EventArgs e ) {
        HeaderRowCount = 0;  // this event starts the binding and row creation process
    }

    // Each row is created and Bound in the order of the dataset.
    protected void GridView1_RowCreated( object sender, GridViewRowEventArgs e ) {

        // Are we creating the Header Row?
        if ( e.Row.RowType == DataControlRowType.Header ) {

            // Create your additional Headers here:  AddHeaderRow() is defined below
            AddHeaderRow( ( GridView ) sender, "Hi I'm a header" );
        }
    }

    protected void GridView1_RowDataBound( object sender, GridViewRowEventArgs e ) {
        if ( e.Row.RowType == DataControlRowType.Header ) {
            HeaderRowCount++;
        }
    }

    protected void GridView1_DataBound( object sender, EventArgs e ) {
        GridView1.Caption = string.Format( "HeaderRowCount: {0}", HeaderRowCount);
    }

After binding is complete you will see this in the GridView Caption:

HeaderRowCount: 1

The header row count will always be 1 because additional header rows are not part of the binding process. The GridView Rows collection only contain Rows that are part of the DataSet. GridViews generate the HeaderRow (and FooterRow) dynamically.

Any additional Header Rows are only available through the inner Table collection of rows, so you need to search each Table Row for RowType == Header:

    Table InnerTable = ( Table ) GridView1.Controls[ 0 ];

    foreach ( GridViewRow r in InnerTable.Rows ) {
        if (r.RowType == DataControlRowType.Header){
            CheckBox chk = (CheckBox) r.FindControl( "chk" );
        }
    }

Or you can access the rows directly if you wish:

    GridViewRow r = ( GridViewRow ) InnerTable.Rows[0];
    CheckBox chk = (CheckBox) r.FindControl( "chk" );

AddHeaderRow()

    private void AddHeaderRow( GridView gv, string HeaderText ) {
        Table InnerTable = ( Table ) gv.Controls[ 0 ];

        GridViewRow row = new GridViewRow( 0, -1, DataControlRowType.Header, DataControlRowState.Normal );
        TableCell th = new TableHeaderCell();


        th.HorizontalAlign = HorizontalAlign.Center;
        th.ColumnSpan = gv.Columns.Count;
        th.Font.Bold = true;
        th.Text = HeaderText;

        row.Cells.Add( th );

        InnerTable.Rows.AddAt( 0, row );
    }

Upvotes: 0

Related Questions