Sooner or later, you may find yourself in the position where you have to serialize and deserialize an object that is a member of one of your classes and of the type System.Drawing.Bitmap. Having a Bitmap as a member of a class is many times preferable over having the raw data be the member, as you only have to initialize the Bitmap once per instance, instead of per use.

You can try to serialize the class as is, and just throw a [Serializable] on top of the class, but you will more than likely run into the following problem:

ObjectDisposedException: Cannot access a closed Stream

This will occur if the original stream used to create the Bitmap is disposed. If you’re like me, you like to release unmanaged resources as soon as your done with them, which means I’m going to close that stream as soon as the Bitmap instance is loaded when I’m sync’ing up with a data source.

If you override ISerializable and try to achieve the serialization by creating a MemoryStream, and then calling the picture’s save message to save it to the stream?(in order to get the byte array), you will get the same error.

Luckily for you, I have another way for you to retrieve the byte contents of a Bitmap; read on for an explanation as to how.

Continue reading »

 

A Typical CollectionViewSource, and the Pain of Sorting

The CollectionViewSource class is used when we want to bind to a CollectionView from XAML in addition to setting various properties such as SortDescriptions and GroupDescriptions. If your design is based on Model-View-ViewModel, you may be using it to bind your ViewModel’s observable collection to the View.

Here is an example of a CollectionViewSource, with a SortDescription defined:

    <CollectionViewSource x:Key="sourceKey"
                          Source="{Binding Path=Data}">
        <CollectionViewSource.SortDescriptions>
            <scm:SortDescription PropertyName="NameOfProp" Direction="Descending"/>
        </CollectionViewSource.SortDescriptions>
    </CollectionViewSource>

The SortDescription defined above will sort the items according to the “NameOfProp” property value of each item. This is convenient, for sure, but you will most likely hit a few brick walls if you are doing anything serious. Specifically, you are going to find out that in order to see a change in sort order within the collection view, you must refresh the collection view. Not only that, but I’m betting that you will eventually come to agree with me that the sorting operation performed by these SortDescriptions is horribly slow.

On top of that, refreshing the collection view itself is horribly expensive. It’s going to block user input and result in a semi-jarring update to the view, depending on the complexity of your items. The sorting operations themselves are painful because they have to rely on the use of Reflection, which will cause a huge performance if hit if you are dealing with a large dataset of complex items.

There is a way you can overcome these limitations, however, and I will show you how within this article. This solution will boost your performance a great deal, but there’s still room for improvement (which I’ll briefly touch on later).

An Idea to Speed Sorting Up

When I was confronted with the problem of the collection view updating too slowly, I first thought about how sorting was being accomplished in the first place. First of all, the sorting behavior was being defined in the CollectionViewSource. The CollectionViewSource is a proxy to a CollectionView; it is useful in that we can switch to different views with it, etc. That aside, it struck me odd that the sorting behavior be defined at this level.

Isn’t it more appropriate to sort on the level of the CollectionView’s data source itself? Instead of relying on the slow SortDescriptions to do the sorting, we should instead remove them and sort the actual contents of the ObservableCollection.

Updates to the ObservableCollection’s items are viewable immediately within the view; it is the change in values used by a SortDescription that results in the need for a refresh. For example, if, in reponse to the values of “NameOfProp” changing, I change the actual order of the items within the collection, the results of that operation will be viewable immediately on the view. This is in contrast to simply calling Refresh() when various values of the “NameOfProp” properties have changed.

This sort of thing can be easily done using a System.Linq.Enumerable extension method like the following:

    TheCollection.OrderBy(p => p.NameOfProp);

The above will return an ordered-by-NameOfProp collection. That’s cool….how do we get this into the ObservableCollection?

The ObservableCollection maintains its items by using its Items property, which happens to be protected. So, we actually can’t use the above code to achieve sorting within our collection.

Defining a Custom ObservableCollection Type

My response to all of the above was to create a class derived from ObservableCollection: SortedObservableCollection.

This class exposes a Sort method that allows you to supply a key selector, allowing you to sort the items inside the collection. The code is more or less provided below.

    public class SortedObservableCollection<T> : ObservableCollection<T>
    {
        /// <summary>
        /// Sorts the items in the collection using the provided key selector.
    	/// </summary>
    	/// <typeparam name="TKey">Key type returned by the key selector.</typeparam>
    	/// <param name="selector">Function to retrieve the key from an item.</param>
    	public void Sort<TKey>(Func<T, TKey> selector)
    	{
    		Sort(Items.OrderBy(selector));
    	}

       /// <summary>
       /// Sorts the items in the collection using the provided key selector.
       /// </summary>
       /// <typeparam name="TKey">Key type returned by the key selector.</typeparam>
       /// <param name="selector">Function to retrieve the key from an item.</param>
       /// <param name="comparer">A <see cref="IComparer{T}"/> to compare keys.</param>
       public void Sort<TKey>(Func<T, TKey> selector, IComparer<TKey> comparer)
       {
            Sort(Items.OrderBy(selector, comparer));
       }

        /// <summary>
        /// Moves items in the inner collection to match the positions of the items provided.
        /// </summary>
        /// <param name="items">
        /// A <see cref="IEnumerable{T}"/> to provide the positions of the items.
        /// </param>
    	private void Sort(IEnumerable<T> items)
    	{
            List<T> itemsList = items.ToList();

    		foreach(T item in itemsList)
    		{
    			Move(IndexOf(item), itemsList.IndexOf(item));
    		}
    	}
    }

That’s all there is to it. Now, use this SortedObservableCollection in place of your ObservableCollections, and when you need to sort the contents, do something like:

    TheCollection.Sort(p => p.NameOfProp);

This will result in the items being sorted according to how you defined the above collection class, which in turn results in the changes being visible on the view at a speed much higher than you were seeing before when you were using just the SortDescriptions.

Thoughts

This shouldn’t be considered a “finished solution” by any means. The ObservableCollection should really be expanded on more, so that it allows multithreaded use and manipulation. The Dispatcher-thread-only nonsense of the ObservableCollection should be seen as a great limitation. Perhaps I’ll provide some of my thoughts on that some other time.

© 2012-2013 Matt Weber. All Rights Reserved. Terms of Use.