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

ericlockshineDirector of ITAsked:
Who is Participating?
I wear a lot of hats...

"The solutions and answers provided on Experts Exchange have been extremely helpful to me over the last few years. I wear a lot of hats - Developer, Database Administrator, Help Desk, etc., so I know a lot of things but not a lot about one thing. Experts Exchange gives me answers from people who do know a lot about one thing, in a easy to use platform." -Todd S.

samtran0331Commented:
Are you using a custom or 3rd party Gridview?
AutoPostBack, DataMemberUniqueID, and EnableMultipleSelect
are not properties of a default asp:Gridview....
0
ericlockshineDirector of ITAuthor Commented:
Custom Grid View.
0
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
Cloud Class® Course: Microsoft Azure 2017

Azure has a changed a lot since it was originally introduce by adding new services and features. Do you know everything you need to about Azure? This course will teach you about the Azure App Service, monitoring and application insights, DevOps, and Team Services.

ericlockshineDirector of ITAuthor 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
ericlockshineDirector of ITAuthor 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
ericlockshineDirector of ITAuthor 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
ericlockshineDirector of ITAuthor 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:
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

Experts Exchange Solution brought to you by

Your issues matter to us.

Facing a tech roadblock? Get the help and guidance you need from experienced professionals who care. Ask your question anytime, anywhere, with no hassle.

Start your 7-day free trial
VelioCommented:
sorry, i was thinking of a datagrid.
0
ericlockshineDirector of ITAuthor 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
ericlockshineDirector of ITAuthor 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
ericlockshineDirector of ITAuthor 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
It's more than this solution.Get answers and train to solve all your tech problems - anytime, anywhere.Try it for free Edge Out The Competitionfor your dream job with proven skills and certifications.Get started today Stand Outas the employee with proven skills.Start learning today for free Move Your Career Forwardwith certification training in the latest technologies.Start your trial today
.NET Programming

From novice to tech pro — start learning today.