iTunes Sample > Searching and Filtering |
Like any song catalog, the one in the sample includes thousands of songs. They are grouped by artist and by album, but scrolling to find a particular song would be impractical.
The sample deals with this by implementing a search box similar to the one used in the real iTunes application. The user types a string into the search box, and the content is automatically filtered to show only songs, artists, or albums with titles that contain the specified string. Here is a brief description of what the SearchBox control looks like and how it works:
The control has two properties:
When the user types into the SearchBox control, a timer starts ticking. When he stops typing for a short while (800ms), the filter is applied to the data source. The filter is not applied immediately after each character is typed because that would be inefficient and annoying to the user.
The timer class used to handle this is defined in the C1FlexGrid assembly. The C1.Util.Timer class is a utility that works in Silverlight and in WPF, making it a little easier to develop applications that share code and run under both platforms.
To apply the filter, the SearchBox control sets the View.Filter property to a method that checks each data item and keeps only those where at least one of the properties specified by the FilterProperties member contains the search string typed by the user.
This is what the code looks like:
C# |
Copy Code
|
---|---|
void _timer_Tick(object sender, EventArgs e) { // stop the timer _timer.Stop(); // check that we have a filter to apply if (View != null && _propertyInfo.Count > 0) { // apply the filter View.Filter = null; View.Filter = (object item) => { // get search text var srch = _txtSearch.Text; // no text? show all items if (string.IsNullOrEmpty(srch)) { return true; } // show items that contain the text in any // of the specified properties foreach (PropertyInfo pi in _propertyInfo) { var value = pi.GetValue(item, null) as string; if (value != null && value.IndexOf(srch, StringComparison.OrdinalIgnoreCase) > -1) { return true; } } // exclude this item... return false; }; } } |
The interesting part of the code is the block that applies the filter. It uses a lambda function instead of a regular method, but the effect is the same. The lambda function uses reflection to retrieve the value of each property specified and checks whether it contains the search string. If a match is found, the item is kept in view. Otherwise, it is filtered out.
To connect the SearchBox control to an application, set the View and FilterProperties properties. In our sample, we set the View property to our song data source and add the Artist, Album, and Name properties to the FilterProperties collection so the user can search for any of these elements. The code that connects the SearchBox to the application looks like this:
C# |
Copy Code
|
---|---|
// configure search box _srchTunes.View = view; foreach (string name in "Artist|Album|Name".Split('|')) { _srchTunes.FilterProperties.Add(typeof(Song).GetProperty(name)); } |