I want to instantiate objects in XAML, and reuse these instances. I think it should be simple but I'm stuck, I'm probably missing something obvious.
Say I want to add Cats to different Rooms (Room has an ObservableCollection containing objects of type Cat). In the UserControl.Resources I create ObjectDataProviders:
<ObjectDataProvider x:Key="Cat1" ObjectType="{x:Type local:Cat}">
<ObjectDataProvider.ConstructorParameters>
<System:String>Tom</System:String>
</ObjectDataProvider.ConstructorParameters>
</ObjectDataProvider>
<ObjectDataProvider x:Key="Cat2" ObjectType="{x:Type local:Cat}">
<ObjectDataProvider.ConstructorParameters>
<System:String>Garfield</System:String>
</ObjectDataProvider.ConstructorParameters>
</ObjectDataProvider>
<ObjectDataProvider x:Key="Cat3" ObjectType="{x:Type local:Cat}">
<ObjectDataProvider.ConstructorParameters>
<System:String>Furball</System:String>
</ObjectDataProvider.ConstructorParameters>
</ObjectDataProvider>
In my UserControl I want to add the Cats to the Rooms:
<local:Room x:Name="Room1">
<local:Room.Cats>
</local:Room.Cats>
<local:Room>
<local:Room x:Name="Room2">
<local:Room.Cats>
</local:Room.Cats>
<local:Room>
What is the syntax for adding the Cat instances to the ObservableCollection Room.Cats? For instance I want to add Cat1 and Cat2 to Room1, and Cat2 and Cat3 to Room2. Am I completely on the wrong track?
Reusing individual instances the way you're trying to do it is tricky. This is because the way that you generally reference single objects in XAML is with the StaticResource
markup extension, and you can only use that markup extension to set a property value.
So you can easily set a property of type Cat
to an instance of a Cat
:
<Room Cat="{StaticResource Cat1}"/>
but you can't populate a collection by setting a property.
The answer, surprisingly, is to instantiate your objects directly in XAML instead of wrapping them in ObjectDataProvider
s. You still use the ObjectDataProvider
, but differently:
<Window x:Class="ObjectDataProviderDemo.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="clr-namespace:ObjectDataProviderDemo"
xmlns:Collections="clr-namespace:System.Collections;assembly=mscorlib"
Title="MainWindow"
Height="350"
Width="525">
<Window.Resources>
<local:Cat x:Key="Tom" Name="Tom"/>
<local:Cat x:Key="Garfield" Name="Garfield"/>
<local:Cat x:Key="Furball" Name="Furball"/>
<Collections:ArrayList x:Key="CatList1">
<ObjectDataProvider ObjectInstance="{StaticResource Tom}" />
<ObjectDataProvider ObjectInstance="{StaticResource Garfield}" />
<ObjectDataProvider ObjectInstance="{StaticResource Furball}" />
</Collections:ArrayList>
<Collections:ArrayList x:Key="CatList2">
<ObjectDataProvider ObjectInstance="{StaticResource Tom}" />
<ObjectDataProvider ObjectInstance="{StaticResource Furball}" />
</Collections:ArrayList>
<DataTemplate x:Key="CatTemplate">
<TextBlock Text="{Binding Name}" />
</DataTemplate>
</Window.Resources>
<StackPanel>
<ListBox ItemsSource="{StaticResource CatList1}"
ItemTemplate="{StaticResource CatTemplate}"/>
<ListBox ItemsSource="{StaticResource CatList2}"
ItemTemplate="{StaticResource CatTemplate}" />
</StackPanel>
</Window>