DataGrid ItemsSource : ObservableCollection<ISomething>

Aug 12, 2008 at 6:18 PM
In that case, the 'look ahead' row is not created since the declared collection item is an interface. A nice feature would be to be able to provide the corresponding class that could serve as a base for instantiation. In the meantime, all such collections have to declare the 'class item' ... or is there an alternative? Thank you, Julie.
Coordinator
Aug 14, 2008 at 2:22 PM

One workaround is to derive from ObservableCollection<ISomething> and start with a non-empty list. For example:

public class Products : ObservableCollection<IProduct>

   {

       public Products()

       {

           Add((new Product("Pro WPF in C# 2008", "Matthew MacDonald", 49.99)));

           Add((new Product("Window Presentation Foundation Unleashed", "Adam Nathan", 49.99)));

           Add((new Product("Programming WPF", "Chris Sells and and Ian Griffiths", 49.99)));

           Add((new Product("WPF Programming", "Chris Andrade, Shawn Livermore, Mike Meyers, and Scott Van Vliet", 49.99)));

           Add((new Product("3D Programming For Windows", "Charles Petzold", 49.99)));

           Add((new Product("Applications = Code + Markup", "Charles Petzold", 49.99)));

           Add((new Product("Practical WPF Graphics Programming", "Jack Xu", 49.99)));

           Add((new Product("Essential Windows Presentation Foundation", "Chris Anderson", 49.99)));

       }

   }

where Product implements IProduct.  You do have to have a non-empty collection to begin with.  Since you derive from ObservableCollection<T> the ListViewCollectionView code will not try to construct the new object with the generic argument (IProduct) and instead will try to get a representative type by actually querying for an item in the list.  In this case it will return a type of Product which as long as there is a default constructor will create the new item for you.

With just ObservableCollection<T>, the framework has to query for the type it has and use reflection to construct it.  If it's an interface it cannot just construct the item solely based on that information.

Aug 15, 2008 at 7:19 AM
One can also note that the following quasi-equivalent construction : " IEditableCollectionView iecv = new ListCollectionView(ObservableCollection<IProduct> as IList); " also leaves the 'CanAddNew' placeholder status of iecv to false.

Such instantiation casts the ObservableCollection<IProduct> to a non-generic IList straight into the constructor of ListCollectionView, that is responsible for the 'CanAddNew' placeholder status.

Despite this, the ListCollectionView will ignore the IList intent and still introspect the provided collection as an "ObservableCollection<IProduct>" and not as a "IList". Based on this mechanism,
it will set the 'CanAddNew' placeholder status to 'false'. If it had taken the "as Ilist" cast into account, it would have discovered the underlying "Product" class type and set the 'CanAddNew' placeholder status to 'true'.