How to get the cell value by column name not by index in GridView in asp.net

I am having a gridview in asp.net and now I want the cell value by the column name but not by the cell index.

How would be it possible by retrieving the cell value by the cell column name


Solution 1:

GridView does not act as column names, as that's it's datasource property to know those things.

If you still need to know the index given a column name, then you can create a helper method to do this as the gridview Header normally contains this information.

int GetColumnIndexByName(GridViewRow row, string columnName)
{
    int columnIndex = 0;
    foreach (DataControlFieldCell cell in row.Cells)
    {
        if (cell.ContainingField is BoundField)
            if (((BoundField)cell.ContainingField).DataField.Equals(columnName))
                break;
        columnIndex++; // keep adding 1 while we don't have the correct name
    }
    return columnIndex;
}

remember that the code above will use a BoundField... then use it like:

protected void GridView_RowDataBound(object sender, GridViewRowEventArgs e)
{
    if (e.Row.RowType == DataControlRowType.DataRow)
    {
        int index = GetColumnIndexByName(e.Row, "myDataField");
        string columnValue = e.Row.Cells[index].Text;
    }
}

I would strongly suggest that you use the TemplateField to have your own controls, then it's easier to grab those controls like:

<asp:GridView ID="gv" runat="server">
    <Columns>
        <asp:TemplateField>
            <ItemTemplate>
                <asp:Label ID="lblName" runat="server" Text='<%# Eval("Name") %>' />
            </ItemTemplate>
        </asp:TemplateField>
    </Columns>
</asp:GridView>

and then use

string columnValue = ((Label)e.Row.FindControl("lblName")).Text;

Solution 2:

Although its a long time but this relatively small piece of code seems easy to read and get:

protected void GridView1_SelectedIndexChanged(object sender, EventArgs e)
{
   int index;
   string cellContent;

    foreach (TableCell tc in ((GridView)sender).HeaderRow.Cells)
    {
       if( tc.Text.Equals("yourColumnName") )
       {
         index = ((GridView)sender).HeaderRow.Cells.GetCellIndex(tc);
         cellContent = ((GridView)sender).SelectedRow.Cells[index].Text;
         break;
       }
    }
}

Solution 3:

You can use the DataRowView to get the column index.

    void OnRequestsGridRowDataBound(object sender, GridViewRowEventArgs e)
    {
        if (e.Row.RowType == DataControlRowType.DataRow)
        {
            var data = e.Row.DataItem as DataRowView;

            // replace request name with a link
            if (data.DataView.Table.Columns["Request Name"] != null)
            {
                // get the request name
                string title = data["Request Name"].ToString();
                // get the column index
                int idx = data.Row.Table.Columns["Request Name"].Ordinal;

                // ...

                e.Row.Cells[idx].Controls.Clear();
                e.Row.Cells[idx].Controls.Add(link);
            }
        }
    }

Solution 4:

For Lambda lovers

protected void GridView_RowDataBound(object sender, GridViewRowEventArgs e)
{
    if (e.Row.RowType == DataControlRowType.DataRow)
    {
        var boundFields = e.Row.Cells.Cast<DataControlFieldCell>()
            .Select(cell => cell.ContainingField).Cast<BoundField>().ToList();

        int idx = boundFields.IndexOf(
            boundFields.FirstOrDefault(f => f.DataField == "ColName"));

        e.Row.Cells[idx].Text = modification;        
    }
}

Solution 5:

Header Row cells sometimes will not work. This will just return the column Index. It will help in a lot of different ways. I know this is not the answer he is requesting. But this will help for a lot people.

public static int GetColumnIndexByHeaderText(GridView gridView, string columnName)
    {      
        for (int i = 0; i < gridView.Columns.Count ; i++)
        {
            if (gridView.Columns[i].HeaderText.ToUpper() == columnName.ToUpper() )
            {
                return i;
            }
        }     
        return -1;
    }