Blog Stats
  • Posts - 18
  • Articles - 0
  • Comments - 26
  • Trackbacks - 76

 

Sortable ASP.NET DropDownList with convenient binding

Often a need arises to have items within a DropDownList sorted.  There are a few options for performing this action:

  1. If the information is coming from the DB, use SQL to presort the items that will be bound to the DropDownList.  The primary advantage to this approach is simplicity.  The primary drawback is that you're now locked into a sorting scheme unless you modify the stored procedure to sort by another column.
  2. If the information is contained within a DataSet or within a collection of business objects, then the DataSet can be sorted or an IComparer can be added to each custom collection.  Here again, if you want to support multiple sorting options for the DropDownList, the logic is spread out amongst various classes.  For example, if you want to sort a DropDownList of Employee objects by Username in one case and by EmployeeNumber in another case, you'll need to have two separate IComparer classes - or at least a more complicated generic IComparer.
  3. To keep DropDownList sorting logic simple and encapsulated, create a DropDownList server control to manage sorting itself.  The primary advantages to this approach are centralizing sorting logic while still providing the flexibility to sort upon any DataSource field/property you so choose with no additional code.

Along with sorting, it is often the case that you may want to provide a ToolTip as the first DropDownList option; such as “-- Select Employee --.”  The below example allows you to conveniently bind a DataSource to a DropDownList along with a ToolTip.  The method SortByText may then be called to sort the DropDownList by text; the method bypasses including the ToolTip in the sort, if provided.

public class SortableDropDownList : DropDownList

{

///

/// Binds a collection of objects to the DropDownList. Automatically calls DataBind()

///

/// Bound to DataSource

/// Bound to DataTextField

/// Bound to DataValueField

/// Used to supply the initial option such as "-- Select --" (Optional)

public void BindDataSource(ICollection dataSource, string dataTextField, string dataValueField, ListItem toolTip) {

DataSource = dataSource;

DataTextField = dataTextField;

DataValueField = dataValueField;

DataBind();

 

if (toolTipListItem != null) {

Items.Insert(0, toolTip);

firstItemIsToolTip = true;

}

}

 

///

/// Sorts the dropdown list by its text value. The ToolTip list item

/// will not be included in the sort if it was provided.

///

public void SortByText() {

if (Items.Count > 0) {

int indexToStartSorting = 0;

int countOfItemsToSort = Items.Count;

if (firstItemIsToolTip) {

indexToStartSorting++;

countOfItemsToSort--;

}

 

ArrayList sortedListItems = new ArrayList(Items);

sortedListItems.Sort(indexToStartSorting, countOfItemsToSort, new ListItemComparer());

Items.Clear();

Items.AddRange((ListItem[]) sortedListItems.ToArray(typeof(ListItem)));

}

}

 

private class ListItemComparer : IComparer {

public int Compare(object listItem1, object listItem2) {

return ((ListItem)listItem1).Text.CompareTo(((ListItem)listItem2).Text);

}

}

 

private bool firstItemIsToolTip = false;

protected override void RenderContents(HtmlTextWriter writer) {

base.RenderContents(writer);

}

}

 


 

Listed below are the unit tests for verifying functionality:

 

[TestFixture]

public class SortableDropDownListTests {

[Test]

public void TestSortByTextWithoutTooltip() {

SortableDropDownList dropDownList = new SortableDropDownList();

dropDownList.BindDataSource(GetRandomItems(), "Name", "ID", null);

dropDownList.SortByText();

 

Assert.AreEqual("Cat", dropDownList.Items[0].Text);

Assert.AreEqual("Dog", dropDownList.Items[1].Text);

Assert.AreEqual("Zebra", dropDownList.Items[2].Text);

}

 

[Test]

public void TestSortByTextWithToolTip() {

SortableDropDownList dropDownList = new SortableDropDownList();

dropDownList.BindDataSource(GetRandomItems(), "Name", "ID", new ListItem("-- Select --"));

dropDownList.SortByText();

 

Assert.AreEqual("-- Select --", dropDownList.Items[0].Text);

Assert.AreEqual("Cat", dropDownList.Items[1].Text);

Assert.AreEqual("Dog", dropDownList.Items[2].Text);

Assert.AreEqual("Zebra", dropDownList.Items[3].Text);

}

 

private RandomItem[] GetRandomItems() {

RandomItem item1 = new RandomItem(1, "Cat");

RandomItem item2 = new RandomItem(2, "Zebra");

RandomItem item3 = new RandomItem(3, "Dog");

 

return new RandomItem[] { item1, item2, item3 };

}

 

private class RandomItem {

public RandomItem(int id, string name) {

this.id = id;

this.name = name;

}

 

public int ID {

get { return id; }

}

 

public string Name {

get { return name; }

}

 

private int id;

private string name;

}

}


Feedback

# re: Sortable ASP.NET DropDownList with convenient binding

Gravatar edit your site so the text doesn't hit my left border. It's killing me to just try and read something. Other than that... thx for the info. 5/31/2006 7:21 AM | JB

# re: Sortable ASP.NET DropDownList with convenient binding

Gravatar btw... I use firefox 5/31/2006 7:23 AM | JB

# re: Sortable ASP.NET DropDownList with convenient binding

Gravatar Thanks for the comment, but I don't have any control over the site. I'm not sure who runs it actually. I occassionally have problems in IE as well. 5/31/2006 7:45 AM | Billy

# re: Sortable ASP.NET DropDownList with convenient binding

Gravatar Well use a different blog site then FFS, this thing is screwed in IE and in Firefox. 1/29/2008 10:42 PM | someone

# re: Sortable ASP.NET DropDownList with convenient binding

Gravatar Dude your blog sucks in FireFox 3 7/30/2008 5:18 AM | Ed

# re: Sortable ASP.NET DropDownList with convenient binding

Gravatar FireFor 3 sucks 8/18/2008 9:30 PM | Andrew

Post a comment





 

 

 

Copyright © Billy McCafferty