Wednesday, 28 July 2010

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 here to 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 IQueryable Skip 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("<<>, "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("<<>
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 Object, ByVal 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