Pages

Friday, November 11, 2011

ASP.NET DropDownList with Custom Paging


Let me start this article off by saying this is something I thought would be interesting to try as an exercise, but it might not fit into a real world scenario. All I wanted to achieve with this is if you can think of something cool to do in ASP.NET, try it! I was thinking about websites that have drop down lists that contain hundreds of items. I thought it would be nice to be able to page through the DropDownList items like you can do with a GridView. Well I came up with a solution!
For this example I’ll be connecting to the Northwind database. If you don’t have a copy of it, you can go hereto download it.
Open Visual Studio 2008 and choose File > New > Web > ASP.NET Web Application.
 
New_Project
 
Open the page and drag a DropDownList control onto the page. Rename this control to cboNames:
 
<asp:DropDownList ID="cboNames" runat="server" AutoPostBack="True"
        OnSelectedIndexChanged="cboNames_SelectedIndexChanged">
    </asp:DropDownList> 
 
I’ve set AutoPostBack to true because I want to be able to page through the data. This example will use LINQ to SQL as the data access layer. Add a new LINQ to SQL Classes file to the project:
 
Add_NewWebApplication
 
Open the LINQ to SQL file in the designer and drag the Customers table onto the designer:
 
Linq_To_SQL
 
So now we have our code that connects to the database, let’s add the code to page through the data. For this to work I’ll be making use of the IQueryableSkip and Take methods. They take an integer value so it knows where to start and how many records to return from the query. Because these values will need to be saved during a postback, I’ll add them as properties that save the value to the ViewState:
 
C#
 
private int Take
{
      get
      {
            return (int)ViewState["Take"];
      }
      set
      {
            ViewState["Take"] = value;
      }
}
 
private int Skip
{
      get
      {
            return (int)ViewState["Skip"];
      }
      set
      {
            ViewState["Skip"] = value;
      }
}
 
VB.NET
 
Private Property Take() As Integer
      Get
             Return CInt(Fix(ViewState("Take")))
      End Get
        Set(ByVal value As Integer)
             ViewState("Take") = value
       End Set
End Property
 
Private Property Skip() As Integer
      Get
             Return CInt(Fix(ViewState("Skip")))
      End Get
       Set(ByVal value As Integer)
             ViewState("Skip") = value
       End Set
End Property
 
 
Now it’s time for the rest of the code. The bulk of the work is handled by the FetchData method:
 
C#
 
private void FetchData()
{
      using (NorthwindDataContext dc = new NorthwindDataContext())
      {
            cboNames.Items.Clear();               
            if (Skip > 0)
            {                   
            cboNames.Items.Add(new ListItem("<< Pre 10 Rows...""Prev"));
             cboNames.AppendDataBoundItems = true;                   
            }
 
            var query = dc.Customers
                            .OrderBy(o => o.ContactName)
                            .Take(Take)
                            .Skip(Skip);
            cboNames.DataTextField = "ContactName";
            cboNames.DataSource = query.ToList();
            cboNames.DataBind();
 
            if (cboNames.Items.Count >= 10)
            {
              cboNames.Items.Add(new ListItem("Next 10 Rows >>""Next"));   
            }
            cboNames.SelectedIndex = Skip > 0 ? 1 : 0;
      }
}
 
VB.NET
 
Private Sub FetchData()
      Using dc As New NorthwindDataContext()
             cboNames.Items.Clear()
                  If Skip > 0 Then
                        cboNames.Items.Add(New ListItem("<< Pre 10 Rows...", "Prev"))
                   cboNames.AppendDataBoundItems = True
                  End If
 
                  Dim query = dc.Customers.OrderBy(Function(o) o.ContactName).Take(Take).Skip(Skip)
                  cboNames.DataTextField = "ContactName"
                  cboNames.DataSource = query.ToList()
                  cboNames.DataBind()
 
                  If cboNames.Items.Count >= 10 Then
                   cboNames.Items.Add(New ListItem("Next 10 Rows >>", "Next"))
                  End If
                  cboNames.SelectedIndex = If(Skip > 0, 1, 0)
      End Using
End Sub
 
In the method above I first check to see if the Skip property is greater than zero. If it is then the user has moved from the first page and this is how they’ll navigate to the previous page. I am setting AppendDataBoundItems to true also. Without that once the data is bound to the control, all the existing values would be removed from the control. Next I am using LINQ to query the Customers object and return the rows between the Take and Skip values. This means at any time I will only return a subset of data making each call to the database as small as possible. Finally once the data has been bound to the control, I look at the number of items in the control. If it is greater or equal to 10 then I’ll display a Next 10 Rows >> link. The user can click on this to navigate to the next page.
 
Finally add the code to the SelectedIndexChanged event:
 
C#
 
protected void cboNames_SelectedIndexChanged(object sender, EventArgs e)
{
      if (cboNames.SelectedValue == "Next")
      {
            Take += 10;
            Skip += 10;
            FetchData();
      }
      else if (cboNames.SelectedValue == "Prev")
      {
            Take -= 10;
            Skip -= 10;
            FetchData();
      }  
}
 
VB.NET
 
Protected Sub cboNames_SelectedIndexChanged(ByVal sender As ObjectByVal e As EventArgs)
      If cboNames.SelectedValue = "Next" Then
             Take += 10
                  Skip += 10
                  FetchData()
       ElseIf cboNames.SelectedValue = "Prev" Then
             Take -= 10
                  Skip -= 10
                  FetchData()
       End If
End Sub
 
The Take and Skip values are incremented or decremented depending on whether or not the user selected Next or Previous. If you run the application you’ll see you have the option to page through the data like you can do in a GridView control:
 
Data
 
To make this code event better you could wrap up the DropDownList inside an UpdatePanel. That would make the transitions between postbacks slick. As I said this example was just an exercise of what you can do using ASP.NET. I enjoyed creating it and I hope you enjoyed it too.

The entire source code of this article can be  downloaded from here.

No comments:

Post a Comment