Search code examples
c#silverlightxamlsilverlight-3.0dependencyobject

Enabling direct content creation in XAML on a dependancy object


I have a class CollectionOfThings. As its name suggests its a simple collection of instances of the Thing class. Thing class has a public default constructor and two simple public get, set properties ID and DisplayName, both are string. CollectionOfThing also has public default constructor.

In XAML I would like to use markup like this:-

<Grid.Resources>
    <local:CollectionOfThings x:Key="Things">
        <local:Thing ID="1" DisplayName="Hello" />
        <local:Thing ID="2" DisplayName="World" />
    <local:CollectionOfThings>
</Grid.Resources>

All is good as long as CollectionOfThings derives from a Collection type. However I want CollectionOfThings to also be a DependencyObject. I thought that's fine creating an implementation of ICollection<T>, INotifyCollectionChanged etc is not that hard. Then I can derive from DependencyObject.

Unfortunately ICollection<T> doesn't cut it for some reason. With ICollection<Thing> I get 'CollectionOfThings does not support Thing as content'. Go back to Collection<Thing> and everything works but leaves me without a DependencyObject implementation.

Suggestions anyone?


Solution

  • XAML wants System.Collections.IList (the non-generic one!) for collections. If you only implement generic IList<T> interface, it won't cut it.

    It also expects to see public Add methods on the class, and derives suitable child types for the collection from arguments of those methods. So the typical approach is to explicitly implement IList - so that its Add(object) method isn't public, and thus isn't picked by XAML parser - and then implicitly implement IList<T> for all child types that you want to support.

    The reason why it works for most built-in collection types (List<T>, Collection<T> etc) is because they follow the pattern above and implement both generic and non-generic interfaces.