Peter
Peter

Reputation: 121

How to make dynamic column header clickable in gridview

I have a gridview with many columns. It's sortable, Allow Sorting="True", each column has Sort Expression. For each column sorting works just fine, except for 10 columns that have dynamic headers that I assign in Row_Databound event:

protected void gvSearchResults_RowDataBound(object sender, GridViewRowEventArgs e)
{
    if (e.Row.RowType == DataControlRowType.Header)
    {
        for (int i = 1; i < 11; i++)
        {
            if (Session["Label" + i.ToString()] !=null)
            {
                e.Row.Cells[i].Text = Session["Label" + i.ToString()].ToString();
            }
        }

    }
}

These 10 columns are not clickable. Is there any way to make them clickable? Everything else in these columns is enabled for sorting.

I've got some suggestions from a different forum about creating columns in Page_Load or Page_Init events, but this probably won't work for me.

Thank you.

Upvotes: 1

Views: 1516

Answers (3)

Peter
Peter

Reputation: 121

Thank you very much for your help. The solution with LinkButton worked great for me:

    protected void gvSearchResults_RowDataBound(object sender, GridViewRowEventArgs e)
{
    if (e.Row.RowType == DataControlRowType.Header)
    {
        for (int i = 1; i < 11; i++)
        {
            if (Session["Label" + i.ToString()] !=null)
            {
                ((LinkButton)(e.Row.Cells[i].Controls[0])).Text = Session["Label" + i.ToString()].ToString();
            }
        }

    }
}

Upvotes: 0

Martin Parenteau
Martin Parenteau

Reputation: 73761

You can replace the text of the existing LinkButton in the header cell:

protected void gvSearchResults_RowDataBound(object sender, GridViewRowEventArgs e)
{
    if (e.Row.RowType == DataControlRowType.Header)
    {
        for (int i = 1; i < 11; i++)
        {
            string caption = Session["Label" + i.ToString()] as string;

            if (caption != null)
            {
                TableCell headerCell = e.Row.Cells[i];
                LinkButton lnkSort = headerCell.Controls[0] as LinkButton;
                lnkSort.Text = caption;
            }
        }
    }
}

Upvotes: 1

VDWWD
VDWWD

Reputation: 35544

It can be done. If you look at the HTML code you will see something similar to this as the link for sorting the GridView.

<a href="javascript:__doPostBack('ctl00$mainContentPane$ctl02$GridView1','Sort$sortExpression')">yourColumnName</a>

We need to recreate that link in the RowDataBound function.

for (int i = 1; i < 11; i++)
{  
    //first we cast the sender as a gridview
    GridView gv = sender as GridView;

    //get the unique ID of the gridview, this is different from ClientID which you normally would use for JavaScipt etc
    string uniqueID = gv.UniqueID;

    //then get the SortExpression for the column
    string sortExpression = gv.Columns[i].SortExpression;

    //get the new column name from the session
    string yourColumnName = string.Empty;
    if (Session["Label" + i.ToString()] != null)
    {
        yourColumnName = Session["Label" + i.ToString()].ToString();
    }

    //and then we fill the header with the new link
    e.Row.Cells[i].Text = "<a href=\"javascript:__doPostBack('" + uniqueID + "','Sort$" + sortExpression + "')\">" + yourColumnName + "</a>";
}

However for this to work, enableEventValidation has to be set to false, which is NOT recommended. Otherwise you will get the "Invalid postback or callback argument" error.

Better would be changing the column names somehow before the data is bound to the gridview.

Upvotes: 0

Related Questions