Click here to Skip to main content
65,938 articles
CodeProject is changing. Read more.
Articles
(untagged)

A paged searchable ListBox control in Silverlight 2

0.00/5 (No votes)
21 Jul 2009 1  
How to implement paging and filtering on a Silverlight 2 ListBox.

Introduction

I had the need to use a ListBox control in a Silverlight 2 project to display many items (there were about 1500 players' names), and I faced some big performance problems: when binding the ListBox (just setting its ItemSource property), it takes more and more seconds to render the final control with the items loaded. Something not acceptable from a user experience perspective. Okay, everybody could ask "how useful is to show so many elements to the user"? In fact, also in my opinion, a user interface designed to show such big lists of items without any filtering facility for the user is the result of a poor design. But, I actually had this scenario: provide the users an alphabetical list of all the 1500 players, letting them to search a player by using a filter or eventually by scrolling the list alphabetically.

I immediately realized that a solution could be to provide the user with a "simulated" complete list: loading just the first items, letting them think it was the complete list, then intercepting the scrolling action to actually load more items. In other words: something similar to the lazy loading of records we see in the GUI of products like MS Access or SQL Server. But, even after loading items "on demand", the list became more and more heavy while scrolling, due to the increased number of loaded items, and the performance problems arose again. Then, I decided to abandon the "progressive loading" approach in favor of a "paged loading" approach combined with a search facility. The following paragraphs describe how I implemented this simple idea.

How the "paged searchable ListBox control" works

The attached sample code contains three experimental ListBoxes, used to show a big number of items, in-memory generated (and hosted by the AllItems list).

PagedListbox

In all the three examples, I'm using the classic, standard Silverlight 2 ListBox control, but in different ways. And in all the three examples, the search facility is provided by the following simple function that uses a LINQ expression to extract from the complete list only the items containing a given string:

Private Function FilterItems(ByVal FilterTerm As String) As IEnumerable(Of String)
    Dim result As IEnumerable(Of String)
    If FilterTerm = "" Then
        ' No filter currently applied
        result = AllItems
    Else
        ' Find out (locally, in memory) the subset of Items containing the search term
        result = From s In AllItems Where 
          s.ToString().ToLower().Contains(FilterTerm.ToLower()) Select s
    End If

    Return result
End Function

In the first ListBox, a simple binding is performed:

lstList1.ItemsSource = AllItems

As you can experiment by yourself on Silverlight 2, for 1500 elements or more, the loading performance is unacceptable. By using the search facility, the user can narrow down the number of items loaded in the ListBox, but while typing the very first characters, the slowness remains unacceptable (until the filtered list is small enough to render quickly).

In the second and third ListBoxes, I'm using a "paged" approach. This means that the ListBox contains a limited number of items, and the user is presented with some visual clue to navigate through the pages. The only difference between the second and the third example is in the visual clue presented to the user in order to navigate the pages: in example 2, it's immediately clear that the list is paged; in example 3, the clue is integrated as an additional list element the user discovers only by scrolling down the ListBox. By keeping track of the number of the page currently displayed and the page dimension, the binding expression in these cases becomes something like:

lstList.ItemsSource = FilteredItems.Skip(PageNumber * PageDimension).Take(PageDimension)

With PageDimension equals to, let's say, fifty, the ListBox will never contain more than 50 items. Any rendering slowness is disappeared, and the user-friendliness is quite completely preserved.

Conclusions

The "paged searchable approach" described here is very simple, but it became absolutely a need for me to workaround the loading and rendering slowness of the Silverlight 2 ListBox control. The good news is that the ListBox control on Silverlight 3 seems to be free from these performance issues, because it now supports UI virtualization.

License

This article has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.

A list of licenses authors might use can be found here