ObservableCollection in WinRT

I have been learning WinRT, new Windows 8 run time for developing Windows 8 application for a little while now.  I am using my CodePlex project as study project.  One of my goals is have an ability to persist collections of object into file system, loosely called database.  I really want my collections to be bindable, so I attempted to use ObservableCollection<T> as the base class for my collections.  This worked just find in Windows Phone 7 and Silverlight based projects.  The same however does not hold true in WinRT.  It contains a number of bases classes that WinRT controls such as ListBox listen to instead of INotifyCollectionChanged.  Specifically, it is IObservableVector<T>.  There is a sample implementation in one of the WinRT sample apps, but I really did not like how it was done – via extension method on INotifyCollectionChanged.  What I really wanted to do is extend Observable Collection, because I think Microsoft will eventually have an implementation for IObservableVector<T>, maybe they would event extend the observable collection itself.  First thing I ran into is that if you use IObservableVector with T anything other than object, your program will throw “bad image” exception.  So, here is the outline of my solution.

  • Use Observable Collection as base class
  • Implement IObservableVector<object>

That should do it, right?

So, I am starting with this declaration:

public class ExtendedObservableCollection<T> : ObservableCollection<T>, IObservableVector<object>

Then I use smart tag for IObservableVector and let Visual Studio fill in the necessary interfaces I have to implement.  Then I simply call base methods of Observable Collection for the majority of implementation, casting object to T as necessary.  Simple and efficient, and most importantly, something I could simply remove down the road as WinRT API becomes more mature.  Here is the final class.

using System;
using
System.Collections.Generic;
using
System.Collections.ObjectModel;
using
Windows.Foundation.Collections;
 

namespace
WinRTDatabase.Core
{
   
/// <summary>

   
/// Class that works for data bindings for WinRT list based controls
   
/// </summary>
   
/// <typeparam name="T"></typeparam>
   
public class ExtendedObservableCollection<T> : ObservableCollection<T>, IObservableVector<object>
    {
 
       
/// <summary>

       
/// Raises collection changed event
       
/// </summary>
       
/// <param name="e">Event arguments for collection changed event</param>
       
protected override void OnCollectionChanged(System.Collections.Specialized.NotifyCollectionChangedEventArgs e)
        {
           
base
.OnCollectionChanged(e);
           
switch
(e.Action)
            {
               
case
System.Collections.Specialized.NotifyCollectionChangedAction.Add:
                    OnVectorChanged(CollectionChange.ItemInserted, (
uint
)e.NewStartingIndex);
                   
break
;
               
case
System.Collections.Specialized.NotifyCollectionChangedAction.Move:
                    OnVectorChanged(CollectionChange.Reset, (
uint
)e.NewStartingIndex);
                   
break
;
               
case
System.Collections.Specialized.NotifyCollectionChangedAction.Remove:
                    OnVectorChanged(CollectionChange.ItemRemoved, (
uint
)e.OldStartingIndex);
                   
break
;
               
case
System.Collections.Specialized.NotifyCollectionChangedAction.Replace:
                    OnVectorChanged(CollectionChange.ItemChanged, (
uint
)e.NewStartingIndex);
                   
break
;
               
case
System.Collections.Specialized.NotifyCollectionChangedAction.Reset:
                    OnVectorChanged(CollectionChange.Reset, (
uint
)e.NewStartingIndex);
                   
break
;
               
default
:
                   
break
;
            }
        }
       
protected void OnVectorChanged(CollectionChange collectionChange, uint
index)
        {
           
if (VectorChanged != null
)
            {
                VectorChanged(
this, new VectorChangedEventArgs
(collectionChange, index));
            }
        }
 
       
public event VectorChangedEventHandler<object
> VectorChanged;
 
       
public int IndexOf(object
item)
        {
           
return base
.IndexOf((T)item);
        }
 
       
public void Insert(int index, object
item)
        {
           
base
.InsertItem(index, (T)item);
        }
 
       
public new object this[int
index]
        {
           
get

            {
               
return base[index];
            }
           
set

            {
               
base[index] = (T)value;
            }
        }
 
       
public void Add(object
item)
        {
           
base
.Add((T)item);
        }
 
       
public bool Contains(object
item)
        {
           
return base
.Contains((T)item);
        }
 
       
public void CopyTo(object[] array, int
arrayIndex)
        {
            T[] newArray =
new
T[array.Length];
           
for (int
i = 0; i < array.Length; i++)
            {
                newArray[i] = (T)array[i];
            }
            CopyTo(newArray, arrayIndex);
        }
 
       
public bool
IsReadOnly
        {
           
get { return false
; }
        }
 
       
public bool Remove(object
item)
        {
           
if
(Contains(item))
            {
               
base
.Remove((T)item);
               
return true
;
            }
           
return false
;
        }
 
       
public new IEnumerator<object
> GetEnumerator()
        {
           
return base.GetEnumerator() as IEnumerator<object
>;
        }
    }
}

 

Thanks.