在XAML中实例化和重用对象的实例

eri*_*200 3 wpf xaml object objectdataprovider instances

我想在XAML中实例化对象,并重用这些实例.我认为它应该很简单但是我被卡住了,我可能会错过一些明显的东西.

假设我想将Cats添加到不同的房间(Room有一个包含Cat类型对象的ObservableCollection).在UserControl.Resources中,我创建了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>
Run Code Online (Sandbox Code Playgroud)

在我的UserControl中,我想将Cats添加到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>
Run Code Online (Sandbox Code Playgroud)

将Cat实例添加到ObservableCollection Room.Cats的语法是什么?例如,我想将Cat1和Cat2添加到Room1,将Cat2和Cat3添加到Room2.我完全走错了路吗?

Rob*_*ney 6

按照您尝试执行此操作的方式重用单个实例非常棘手.这是因为您通常在XAML中引用单个对象的方式是使用StaticResource标记扩展,并且您只能使用该标记扩展来设置属性值.

因此,您可以轻松地将类型的属性设置Cat为以下实例Cat:

<Room Cat="{StaticResource Cat1}"/>
Run Code Online (Sandbox Code Playgroud)

但您无法通过设置属性来填充集合.

令人惊讶的是,答案是直接在XAML中实例化对象,而不是将它们包装在ObjectDataProviders中.你仍然使用ObjectDataProvider,但不同:

<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>
Run Code Online (Sandbox Code Playgroud)