In this article I will explain with some examples, how to use multiple DataKeyNames (DataKeys) in ASP.Net GridView.
What are DataKeyNames and DataKeys?
To get detailed explanation about DataKeyNames and DataKeys, please refer my article Understanding ASP.Net GridView DataKeyNames (DataKeys).
HTML Markup
For the below GridView I have set multiple DataKeyNames i.e. Id and Group. Both the DataKey values will be fetched on Button click.
<asp:GridView ID="GridView1" runat="server" AutoGenerateColumns="false" DataKeyNames="Id, Group">
    <asp:BoundField DataField="Name" HeaderText="Name" ItemStyle-Width="150" />
    <asp:BoundField DataField="Country" HeaderText="Country" ItemStyle-Width="100" />
            <asp:Button ID="Button1" Text="Get Value" runat="server" OnClick="GridView_Button_Click" />
You will need to import the following namespaces.
using System.Data;
Imports System.Data
Binding the GridView
The GridView is populated using some dummy records using DataTable.
protected void Page_Load(object sender, EventArgs e)
    if (!this.IsPostBack)
        DataTable dt = new DataTable();
        dt.Columns.AddRange(new DataColumn[4] { new DataColumn("Id"), new DataColumn("Group"), new DataColumn("Name"), new DataColumn("Country") });
        dt.Rows.Add(1, "A", "John Hammond", "United States");
        dt.Rows.Add(2, "B", "Mudassar Khan", "India");
        dt.Rows.Add(3, "A", "Suzanne Mathews", "France");
        dt.Rows.Add(4, "B", "Robert Schidner", "Russia");
        GridView1.DataSource = dt;
Protected Sub Page_Load(sender As Object, e As EventArgs) Handles Me.Load
    If Not Me.IsPostBack Then
        Dim dt As New DataTable()
        dt.Columns.AddRange(New DataColumn(3) {New DataColumn("Id"), New DataColumn("Group"), New DataColumn("Name"), New DataColumn("Country")})
        dt.Rows.Add(1, "A", "John Hammond", "United States")
        dt.Rows.Add(2, "B", "Mudassar Khan", "India")
        dt.Rows.Add(3, "A", "Suzanne Mathews", "France")
        dt.Rows.Add(4, "B", "Robert Schidner", "Russia")
        GridView1.DataSource = dt
    End If
End Sub
Getting the value of multiple DataKeys for a particular GridView Row
Inside the Button click event handler, first the GridView Row is determined using the NamingContainer property and then finally the Row Index is determined.
Using the Row Index, the DataKeys array is accessed and the value of the Column is fetched.
DataKeys follow 0 based index i.e. the value of the first DataKey column is available at 0th index.
The Id column is set first followed by the Group field and hence the value of the Id field is available at 0th index, while the value of the Group field is available at the 1st index.
Thus in the same way the 3rd column will be available at 2nd index and so on.
protected void GridView_Button_Click(object sender, EventArgs e)
    //Determine the RowIndex of the Row whose Button was clicked.
    int rowIndex = ((sender as Button).NamingContainer as GridViewRow).RowIndex;
    //Get the value of column from the DataKeys using the RowIndex.
    int id = Convert.ToInt32(GridView1.DataKeys[rowIndex].Values[0]);
    string group = GridView1.DataKeys[rowIndex].Values[1].ToString();
Protected Sub GridView_Button_Click(sender As Object, e As EventArgs)
    'Determine the RowIndex of the Row whose Button was clicked.
    Dim rowIndex As Integer = TryCast(TryCast(sender, Button).NamingContainer, GridViewRow).RowIndex
    'Get the value of column from the DataKeys using the RowIndex.
    Dim id As Integer = Convert.ToInt32(GridView1.DataKeys(rowIndex).Values(0))
    Dim group As String = GridView1.DataKeys(rowIndex).Values(1).ToString()
End Sub