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. 

Pass Multiple Values from a GridView to Another Page using ASP.NET

A common requirement in our projects is to select a GridView row and pass multiple values of the selected row to another page. I recently got a request from a few readers who wanted an article on this. In this article, we will explore how simple it is to achieve this requirement.
I assume you have some basic understanding of the GridView and how to bind it to a Data Source control. The Hyperlink control added to the GridView makes it quiet easy to select a row and send single/multiple values to a different page through the URL. Let us see how:
Step 1: Create a new ASP.NET website. Drag and drop a SqlDataSource Control to the page and use the wizard to connect to the Northwind database. Select the CustomerId, CompanyName, ContactName, Address and City from the Customers table. The wizard will also prompt you to save the connection string in the web.config file. Choose to do so. The design code will look similar to the following:

<asp:SqlDataSource ID="SqlDataSource1" runat="server" ConnectionString="<%$ ConnectionStrings:NorthwindConnectionString %>"
            SelectCommand="SELECT [CustomerID], [CompanyName], [ContactName], [Address], [City] FROM [Customers]">
        asp:SqlDataSource>
An entry will be added to the web.config file as shown below:

<connectionStrings>
            <add name="NorthwindConnectionString" connectionString="Data Source=(local);Initial Catalog=Northwind;Integrated Security=True"providerName="System.Data.SqlClient"/>
      connectionStrings>

Step 2: Now add a GridView control to the page and using the smart tag, select the DataSource to be SqlDataSource1 in the GridView tasks panel. Using the same panel, click on the Enable Paging and Enable Sorting checkboxes. The source will look similar to the following. Observe that the DataKeyNames is set to ‘CustomerId’, that is the primary key of the Customers table.
        <asp:GridView ID="GridView1" runat="server" AutoGenerateColumns="False" DataKeyNames="CustomerID"
            DataSourceID="SqlDataSource1" AllowPaging="True" AllowSorting="True">
            <Columns>           
                <asp:BoundField DataField="CustomerID" HeaderText="CustomerID" ReadOnly="True" SortExpression="CustomerID" />
                <asp:BoundField DataField="CompanyName" HeaderText="CompanyName" SortExpression="CompanyName" />
                <asp:BoundField DataField="ContactName" HeaderText="ContactName" SortExpression="ContactName" />
                <asp:BoundField DataField="Address" HeaderText="Address" SortExpression="Address" />
                <asp:BoundField DataField="City" HeaderText="City" SortExpression="City" />
            Columns>
        asp:GridView>

Step 3: We will now add another page in our project. In the Solution Explorer, right click the project > Add New Item > Web Form > Rename it to ‘CustomerDetails.aspx’.
Step 4: Go back to Default.aspx and add two hyperlink fields. We will see how to pass a single value as well as multiple values using the two hyperlink fields.
Single Value:
Add the following hyperlink control after the <Columns> tag in the GridView as shown below:
<Columns>
<asp:HyperLinkField DataNavigateUrlFields="CustomerID" DataNavigateUrlFormatString="CustomerDetails.aspx?CID={0}" Text="Pass Single Value" />
Multiple Values:
Just below the first hyperlink field, add another hyperlink field as shown below:
<asp:HyperLinkField DataNavigateUrlFields="CustomerID, CompanyName, ContactName, Address, City" DataNavigateUrlFormatString="CustomerDetails.aspx?CID={0}&CName={1}&ContactName={2}&Addr={3}&City={4}" Text="Pass Multiple Values" />


In the source code shown above, we are using the hyperlink field and setting some properties that will make it extremely easy to pass values to a different page. The 'DataNavigateUrlFields' sets the names of the fields, that is to be used to construct the URL  in the HyperLinkField. In the first hyperlink, since we are passing only a single value, the DataNavigateUrlFields contains only CustomerID. However in the second hyperlink, since there are multiple values to be passed, DataNavigateUrlFields contains all the names of the fields that are to be passed as query string to CustomerDetails.aspx
Similarly, the 'DataNavigateUrlFormatString' sets the string that specifies the format in which the URL is to be created. The 'Text' property represents the text that will be displayed to the user. The entire source code will look similar to the following:
<body>
    <form id="form1" runat="server">
    <div>
        <asp:SqlDataSource ID="SqlDataSource1" runat="server" ConnectionString="<%$ ConnectionStrings:NorthwindConnectionString %>"
            SelectCommand="SELECT [CustomerID], [CompanyName], [ContactName], [Address], [City] FROM [Customers]">
        asp:SqlDataSource>
   
    div>
        <asp:GridView ID="GridView1" runat="server" AutoGenerateColumns="False" DataKeyNames="CustomerID"
            DataSourceID="SqlDataSource1" AllowPaging="True" AllowSorting="True">
            <Columns>           
                 <asp:HyperLinkField DataNavigateUrlFields="CustomerID"
                    DataNavigateUrlFormatString="CustomerDetails.aspx?CID={0}"
                     Text="Pass Single Value" />
                   <asp:HyperLinkField DataNavigateUrlFields="CustomerID, CompanyName, ContactName, Address, City"
                    DataNavigateUrlFormatString="CustomerDetails.aspx?CID={0}&CName={1}&ContactName={2}&Addr={3}&City={4}"
                      Text="Pass Multiple Values" />
                <asp:BoundField DataField="CustomerID" HeaderText="CustomerID" ReadOnly="True" SortExpression="CustomerID" />
                <asp:BoundField DataField="CompanyName" HeaderText="CompanyName" SortExpression="CompanyName" />
                <asp:BoundField DataField="ContactName" HeaderText="ContactName" SortExpression="ContactName" />
                <asp:BoundField DataField="Address" HeaderText="Address" SortExpression="Address" />
                <asp:BoundField DataField="City" HeaderText="City" SortExpression="City" />
            Columns>
        asp:GridView>
    </form>
</body>
Step 5: The last step is to retrieve the query string variables from the URL in the CustomerDetails.aspx page. Add the following code for that:
C#
    protected void Page_Load(object sender, EventArgs e)
    {
        string cid = Request.QueryString["CID"];
        string cname = Request.QueryString["CName"];
        string contactName = Request.QueryString["ContactName"];
        string address = Request.QueryString["Addr"];
        string city = Request.QueryString["City"];
    }
VB.NET
      Protected Sub Page_Load(ByVal sender As Object, ByVal e As EventArgs)
            Dim cid As String = Request.QueryString("CID")
            Dim cname As String = Request.QueryString("CName")
            Dim contactName As String = Request.QueryString("ContactName")
            Dim address As String = Request.QueryString("Addr")
            Dim city As String = Request.QueryString("City")
      End Sub
Set a breakpoint at the Page_Load method of the CustomerDetails.aspx. Run the application and click on either the ‘Pass Single Value’ or ‘Pass Multiple Values’ hyperlink to pass values to the CustomerDetails.aspx page. Using the breakpoint, observe the values of the selected row being passed to the CustomerDetails page.
I hope this article was useful and I thank you for viewing it. 

Tuesday, January 4, 2011

Add to Favorites (IE) / Bookmark (Mozilla Firefox, Opera) Page Javascript

Developers basically use shortcut command to add a page into favorite list or bookmark list but most of the users does not know how they can add an important page into their favorite list or bookmark list. Thats why if developer add a bookmark link or add to favorite link on important pages so that users can easily bookmark the page. Here in this article i will explain how one can add favorites link or bookmark link in a page using cross browser javascript code. My example will work on Internet explorer, Opera and Mozilla Firefox like below:

To implement my example code first add a aspxa page into your project then under HTML head tag add the below javascript method to bookmark or add to favorites:


<script type="text/javascript">
    function Add_Bookmark_Favorite(url, title)
    {
        if (window.sidebar)
        { // Mozilla Firefox Bookmark
            //Make sure "Load this bookmark in the sidebar is deselected
            window.sidebar.addPanel(title, url, "");
            return false;
        }
        else if (window.external)
        { // IE Favorites
            window.external.AddFavorite(url, title);
            return false;
        }
        else if (window.opera && window.print)
        { // Opera Bookmark
            return !addToFav(url, title)
        }
    }
script>



Now add the below link into your asp.net aspx page like below:


<a href="" title="" rel="sidebar" onclick="return Add_Bookmark_Favorite(location.href, document.title);">Bookmark / Add to Favoritesa>

Bookmark / Add to Favorites

Now run the page and click on the "Bookmark / Add to Favorites" link will popup a window to bookmark this page.