Extending the ObservableCollection to add navigation methods such as MoveFirst, MoveNext, MoveLast, and MovePrevious.
Recently, I had the need to navigate a list by using methods such as MoveFirts, MovePrevious, MoveNext, and MoveLast while at the same time keeping track of its current location to notify the user where they are at in the list.
Enter the ICollectionView. “You can think of a collection view as a layer on top of a binding source collection that allows you to navigate and display the collection based on sort, filter, and group queries, all without having to manipulate the underlying source collection itself.”, says the MSDN documentation. The ICollectionView supports filtering, sorting, grouping, selection, and navigation.
Now the most common way this is used is by creating your collection, populating it with data, then creating an ICollectionView instance from your collection, and then start sorting, filtering, grouping, etc. The following code show some examples of how to use the ICollectionView.
//get the view
List<MyObject> myList = new List<MyObject>();
ICollectionView view = CollectionViewSource.GetDefaultView(myList);
//filtering
view.Filter = delegate(object item)
{return item.Contains(searchText);};
//sorting
view.SortDescriptions.Add(new SortDescription("LastName", direction));
//grouping
view.GroupDescriptions.Add(new PropertyGroupDescription("State"));
//selection
view.CurrentItem
But I didn’t want to do this every time I had a collection of data I wanted to navigate. I wanted a single generic collection class that encapsulated all this functionality. So I decided to extend the ObservableCollection to allow for this functionality. So the first thing I need to do is create my class, inherit from ObservableCollection, and then create my constructors.
public class MyObservableCollection<T> : ObservableCollection<T>
{
public MyObservableCollection(List<T> list)
: base(list)
{
}
public MyObservableCollection(IEnumerable<T> collection)
: base(collection)
{
}
}
Next I want to create my method to return my instance of ICollectionView.
private System.ComponentModel.ICollectionView GetDefaultView()
{
return System.Windows.Data.CollectionViewSource.GetDefaultView(this);
}
Now, lets create a property to retrieve the currently selected item in the list.
public int CurrentPosition
{
get
{
return GetDefaultView().CurrentPosition;
}
}
Now lets create our four methods for navigating the items in the collection.
public void MoveFirst()
{
GetDefaultView().MoveCurrentToFirst();
}
public void MovePrevious()
{
GetDefaultView().MoveCurrentToPrevious();
}
public void MoveNext()
{
GetDefaultView().MoveCurrentToNext();
}
public void MoveLast()
{
GetDefaultView().MoveCurrentToLast();
}
Now, lets use our new collection. First start off by creating and instance of your custom collection.
MyObservableCollection<MyObject> ProgressItemsList = new MyObservableCollection<MyObject>(data);
In this example I am using a WPF Ribbon to hold my navigation controls, and commanding to execute the navigation methods. The center label maintains the current position and the count of the number of items in the collection.
So now, when I click the Next button I first need to check whether or not I can move to the next record in the command’s CanExecute event.
private bool CanMoveNext(object parameter)
{
bool canExecute = false;
if (ProgressItemsList != null)
{
int currentPosition = ProgressItemsList.CurrentPosition;
int lastIndex = ProgressItemsList.Count - 1;
canExecute = currentPosition < lastIndex;
}
return canExecute;
}
If I can move to the next record, then execute the Execute method of the command.
private void MoveNext(object sender)
{
ProgressItemsList.MoveNext();
}
That is it, and because this is an ObservableCollection, all the changes are notified back to the UI for you automatically. Now you can extend your custom collection even more to customize your sorting, filtering and grouping.
.jpg)
Categories
- .NET 3.5
- Boise Code Camp
- BSDG
- CSLA
- Entity Framework
- Extended WPF Toolkit
- NETDUG
- Prism
- Silverlight
- Uncategorized
- Visual Studio
- WPF
- XAML
Popular Posts
- Silverlight 4 – Accessing System Devices with Com Interop, such as a Scanner.
- Silverlight DataGrid - Populate Dynamic Columns from a Child Collection
- WPF Multithreading: Using the BackgroundWorker and Reporting the Progress to the UI.
- Creating a Custom Silverlight Pre-Loader
- A Simple WPF Loading Animation
- Communicating Between Silverlight Applications
- Text-To-Speech in Silverlight Using WCF
- The Free Office WPF Ribbon
- Extended WPF Toolkit – New MessageBox Control
- Extended WPF Toolkit – New RichTextBox Control
Archives
- September 2010
- August 2010
- July 2010
- June 2010
- May 2010
- April 2010
- March 2010
- February 2010
- January 2010
- December 2009
- November 2009
- September 2009
- August 2009
- July 2009
- June 2009
- May 2009
- April 2009
- March 2009