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

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;

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);
            }
        }
    }

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;
       }
    }
}