Finding Template Column Controls in Header of GridView

Hi All,
I have a gridview that contains columns, and in each column is a template field.  In each template field is a <HeaderTemplate> and an <ItemTemplate>.  Inside the HeaderTemplate is a linkbutton object.

During Databinding (or before if possible), I want to hide certain columns from view based on permissions.  During page init, I get the permissions.

How do I find the link button control listed in the code snippet as HeaderLinkButton1?  How do I hide the entire column from view?  I still want to show the Username column regardless of permissions!

<asp:GridView runat="server" ID="GridView1" EnableMultipleSelect="true" AutoPostBack="true" AutoGenerateColumns="false" DataMemberUniqueID="itsID" DataSourceID="ObjectDataSource" OnSelectedIndexChanged="GridView1_SelectedIndexChanged">
    <Columns>
        <asp:TemplateField>
            <HeaderTemplate>
                <asp:LinkButton ID="HeaderLinkButton1" runat="server" OnCommand="SortLinkButton_Command" CommandName="Sort" CommandArgument="Level" Text="Some Text" />
            </HeaderTemplate>
            <ItemTemplate>
                <%# GetLevel(Container.DataItem) %>
            </ItemTemplate>
        </asp:TemplateField>
        <asp:TemplateField>
            <HeaderTemplate>
                <asp:LinkButton ID="HeaderLinkButton2" runat="server" OnCommand="SortLinkButton_Command" CommandName="Sort" CommandArgument="Username" Text="User Name" />
            </HeaderTemplate>
            <ItemTemplate>
                <%# GetUsername(Container.DataItem) %>
            </ItemTemplate>
        </asp:TemplateField>
	</Columns>
</asp:GridView>

Open in new window

ericlockshineAsked:
Who is Participating?
 
VelioConnect With a Mentor Commented:
in the OnItemDatabound event handler you should be able to identify when a header item is being databound and find the correct linkbutton using the find FindControl method of the row.
0
 
samtran0331Commented:
Are you using a custom or 3rd party Gridview?
AutoPostBack, DataMemberUniqueID, and EnableMultipleSelect
are not properties of a default asp:Gridview....
0
 
ericlockshineAuthor Commented:
Custom Grid View.
0
The new generation of project management tools

With monday.com’s project management tool, you can see what everyone on your team is working in a single glance. Its intuitive dashboards are customizable, so you can create systems that work for you.

 
samtran0331Commented:
with a standard gridview, you could hide the entire column with:
GridView1.Columns[0].Visible = False;

where/when (what event) would you want to find the control in the header?
0
 
ericlockshineAuthor Commented:
This grid view just adds a paging control to the grid view.  It extends the stanard gridview.  It uses the AutoPostBack, DataMemberUniqueID and EnableMultipleSelect as additional fields only.
0
 
ericlockshineAuthor Commented:
When the grid view gets its data, and before it is rendered, I want to hide certain columns based not on position, but on text in the gridview
0
 
ericlockshineAuthor Commented:
I should explain a little further.  There are currently about 14 fields that I need to enable/disable based on priviledge.  At any point, someone other than me can move these columns around.  As a member of a team of about 10, I cannot just say GridView1.Columns[0].Visible = false.  What I need to be able to do is find the column that contains the link button that contains certain text (because the text is in a resource that is bound to the field).
0
 
ericlockshineAuthor Commented:
Here is some code so far that I have been able to figure out.

What I don't know how to do is what to cast the HeaderTemplate as (It shows ITemplate as its base class).  If I knew what kind of object to cast this as, I could possibly find the linkbutton control that it has as a child control.

foreach (DataControlField dcf in GridView1.Columns) //loop through all the columns in the grid
{
    if (dcf is TemplateField) //because someone can put in any kind of control, the only ones I am interested in is the TemplateField controls
    {
        TemplateField tf = (TemplateField)dcf;
        tf.HeaderTemplate;
    }
}

Open in new window

0
 
VelioCommented:
sorry, i was thinking of a datagrid.
0
 
ericlockshineAuthor Commented:
Velio,
I was able to take your suggestion and use it partially.  I have found a GridView_RowDataBound event that takes something similar.  I was eventually able to determine the header control with my text I was looking for.  Thanks for your help!
Now I am stuck again....I have the DataControlFieldHeaderCell object and found the link button in the controls collection.  Now I want to hide the entire column, not just the header cell (which I can do).
How can I reference the entire column now to hide it?  check out the code below

        protected void GridView_RowDataBound(object sender, GridViewRowEventArgs e)
        {
			//GridView1 = GridView Control ID for the grid (from above)
            if (e.Row.RowType == DataControlRowType.Header)
            {
                bool isScanJob = true;
 
                //we have found the header row
                foreach (DataControlFieldHeaderCell dcfhc in e.Row.Cells)
                {
                    if (dcfhc.Controls.Count > 0)
                    {
						//loop through all the controls and find my linkbutton control;
                        foreach (Control ctl in dcfhc.Controls)
                        {
                            if (ctl is LinkButton)
                            {
								//found my link button control.  Hide the ENTIRE COLUMN if my LinkButton contains any of the text here.
                                LinkButton lb = (LinkButton)ctl;
                                if (!isScanJob)
                                {
                                    if ((lb.Text.Equals("Duration"))
                                        || (lb.Text.Equals("Highs"))
                                        || (lb.Text.Equals("Mediums"))
                                        || (lb.Text.Equals("Lows"))
                                        || (lb.Text.Equals("Warnings"))
                                        || (lb.Text.Equals("Informationals"))
                                        || (lb.Text.Equals("Score")))
                                    {
										//stuck here.  This will hide only the cell, not the entire column.
                                        dcfhc.Visible = false;
										//the next line will hide the row, not the column
										dcfhc.Parent.Visible = false;
                                    }
                                }
                            }
                        }
                    }
                }
            }
        }

Open in new window

0
 
VelioCommented:
you can keep an index that you increment with each iteration of your foreach loop, this will give you the index of the column where you find the header cell... you can then use
GridView1.Columns[index].visible = false; when you want to hide it...

i haven't tested if this works, will do so as soon as i get the chance, but try it and let me know.
0
 
ericlockshineAuthor Commented:
I actually found a better way!
dcfhc.ContainingControl.Visible = false;
This will set the entire column to an invisible status, while maintaining the column integrity.
Thanks Velio for the suggestion!  I now have the entire code working the way I want it.  I will post it here

Because you gave me the direction, I'm awarding you the points.  Thanks!

        protected void GridView_RowDataBound(object sender, GridViewRowEventArgs e)
        {
            if (e.Row.RowType == DataControlRowType.Header)
            {
                bool isScanJob = true;
                foreach (DataControlFieldHeaderCell dcfhc in e.Row.Cells)
                {
                    if (dcfhc.Controls.Count > 0)
                    {
                        foreach (Control ctl in dcfhc.Controls)
                        {
                            if (ctl is LinkButton)
                            {
                                LinkButton lb = (LinkButton)ctl;
                                if (!isScanJob)
                                {
                                    if ((lb.Text.Equals("Duration"))
                                        || (lb.Text.Equals("Highs"))
                                        || (lb.Text.Equals("Mediums"))
                                        || (lb.Text.Equals("Lows"))
                                        || (lb.Text.Equals("Warnings"))
                                        || (lb.Text.Equals("Informationals"))
                                        || (lb.Text.Equals("Score")))
                                    {
                                        dcfhc.ContainingField.Visible = false;
                                    }
                                }
                            }
                        }
                    }
                }
            }
        }

Open in new window

0
 
ericlockshineAuthor Commented:
It wasn't the OnItemDataBound event, it was the OnRowDataBound event that is part of the GridView.  I'm still giving you an A because it did point me in the right direction!  Thanks for the help!
0
All Courses

From novice to tech pro — start learning today.