Search This Blog

Thursday, January 6, 2011

Using DataKeyNames in the ASP.NET GridView control

Recently I was asked by a work colleague about what was the best way to hide primary keys when displaying data in a GridView control. I mentioned the DataKeyNames property and got a blank stare. This little gem is a property on the GridView control that allows you to set an array that contains the primary key fields for the items displayed in a GridView control. 
Let’s get started. Open Visual Studio 2008 and create a new Web Application. This example won’t hook into a database, but we will create a class to mock a table and retrieve data from it instead. Right click on the project and choose Add > Class. Name the class Customer. Open the Customer class and add the following code:
public class Customer
{
public int ID { get; set; }
      public string GivenName { get; set; }
      public string Surname { get; set; }
      public string EmailAddress { get; set; }
      public string NickName { get; set; }
}


The Customer class contains five properties. The ID property is going to the unique identifier, so this is to be used internally by the application and should not be displayed to the user.
The next step is to create a collection of Customer objects and bind this to a GridView control. Open the Default.aspx page and the following code:
<asp:GridView ID="grdCustomer" runat="server" AutoGenerateColumns="False"
DataKeyNames="ID" onrowcommand="grdCustomer_RowCommand">
<Columns>               
<asp:CommandField CausesValidation="false" ButtonType="Image" SelectImageUrl="~/Users.gif" ShowSelectButton="true" />
            <asp:BoundField DataField="GivenName" HeaderText="Name" />
<asp:BoundField DataField="Surname" HeaderText="Surname" />
            <asp:BoundField DataField="EmailAddress" HeaderText="Email" />
            <asp:BoundField DataField="NickName" HeaderText="Nick Name" />
Columns>
asp:GridView>
In the code above the DataKeyNames property is set to the ID property. When data is bound to the GridView control, the GridView will look for a property named ID. When it is found, the value will be used as the primary key for each row in the GridView. This enables you to not display the ID to the user, yet still being able to retrieve it.  You can also assign multiple primary keys if desired by separating them with a comma (,). For example you could have the following code:
DataKeyNames="ID,Surname"
This means that now there are two primary key values defined; ID and Surname. A CommandField was also created in the code above. The ButtonType is set to Image, so for each row that is created in the GridView, an image will be displayed to the user. Clicking the image will raise the RowCommand event on the GridView. The purpose of doing this is to show you how to retrieve the DataKey value from the GridView control.
The next step is to create a collection of Customer objects and bind that to the GridView control. Open the Default.aspx page and add the following code:
protected void Page_Load(object sender, EventArgs e)
{
if (!IsPostBack)
      {
            List<Customer> customers = new List<Customer>();
            customers.Add(new Customer()
            {
                  ID = 123,
                  GivenName = "test",
                  Surname = "Customer",
                  EmailAddress = "test@test.com",
                  NickName = "Tester"
            });
            customers.Add(new Customer()
            {
                  ID = 789,
                  GivenName = "Partha",
                  Surname = "Sarathi",
                  EmailAddress = "sarathi@test.com",
                  NickName = "Partha"
});
            grdCustomer.DataSource = customers;
            grdCustomer.DataBind();
}
}

In the code above, I have created a generic List or List(Of Customer) to store the information. I have used a new feature to C# and VB.Net called Object Initialization. This allows you to create a new instance of a class and assign values to properties in one easy step.   Finally the code is bound to the GridView control by calling the DataBind method.
The last piece of code is to create an event handler for the RowCommand event. Open the Default.aspx page in the Design view. Select the GridView. Open the properties and select the lightning bolt to view the events for the GridView:


Double click the RowCommand event and Visual Studio will automatically create the event handler. Add the following code:
C#
protected void grdCustomer_RowCommand(object sender, GridViewCommandEventArgs e)
{
object dataKeyValue = grdCustomer.DataKeys[int.Parse(e.CommandArgument.ToString())].Value;
}

When the user selects a record from the grid, the selected row index will be passed through as the CommandArgument. Run the project and place a breakpoint on the code above. Select a row. The program will stop on the breakpoint and you will be able to see the selected row index being passed through. You can then use the code below to retrieve the ID value:


The DataKeys property expects an integer. From there you can query the Value property to retrieve a single value, or you can query the Values property if you have an array of DataKeys defined.
Now that you have the primary key, you can go ahead and use it to lookup data from another table perhaps. DataKeyNames are a great way to use primary keys without having to display them to the user. If you have more than one primary key, you can separate the values with a comma. This adds extra flexibility to a great property. 

No comments:

Post a Comment

Note: Only a member of this blog may post a comment.