Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/wpf/12.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Wpf 在XAML中实例化和重用对象实例_Wpf_Xaml_Object_Objectdataprovider_Instances - Fatal编程技术网

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

Wpf 在XAML中实例化和重用对象实例,wpf,xaml,object,objectdataprovider,instances,Wpf,Xaml,Object,Objectdataprovider,Instances,我想在XAML中实例化对象,并重用这些实例。我想应该很简单,但我被卡住了,我可能错过了一些明显的东西 假设我想将Cat添加到不同的房间(房间有一个包含Cat类型对象的ObservableCollection)。在UserControl.Resources中,我创建了ObjectDataProviders: <ObjectDataProvider x:Key="Cat1" ObjectType="{x:Type local:Cat}"> <ObjectDataProvid

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

假设我想将Cat添加到不同的房间(房间有一个包含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>

汤姆
加菲猫
Furball
在我的UserControl中,我想将猫添加到房间:

<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>


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

以您尝试的方式重用单个实例是很棘手的。这是因为在XAML中通常引用单个对象的方式是使用
StaticResource
标记扩展,并且只能使用该标记扩展来设置属性值

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

<Room Cat="{StaticResource Cat1}"/>

根据Heinzi和Robert Rossney的反馈,我提出了以下解决方案,该解决方案与我可以在XAML和代码隐藏中访问的ObservableCollection一起工作:

在代码中,我扩展了ObservableCollection,以便在XAML中使用它(在XAML2009中不再需要它):

公共类CatObservableCollection:ObservableCollection{}
在UserControl.Resources中的XAML中,我实例化了CAT:

<local:Cat x:Key="Tom" Name="Tom"/>
<local:Cat x:Key="Garfield" Name="Garfield"/>
<local:Cat x:Key="Furball" Name="Furball"/>

收藏:

<local:CatObservableCollection x:Key="Room1Collection">
    <StaticResourceExtension ResourceKey="Tom"/>
    <StaticResourceExtension ResourceKey="Garfield"/>
</local:CatObservableCollection>
<local:CatObservableCollection x:Key="Room2Collection">
    <StaticResourceExtension ResourceKey="Garfield"/>
    <StaticResourceExtension ResourceKey="Furball"/>
</local:CatObservableCollection>

这些房间现在定义如下:

<local:Room x:Name="Room1" Cats="{StaticResource Room1Collection}"/>
<local:Room x:Name="Room2" Cats="{StaticResource Room2Collection}"/>


房间。猫是一个可观察的集合

为了满足您的特殊需求,您可以选择仿制药。要声明性地使用泛型,必须使用。TypeArguments指令只能与根元素一起使用。所以,现在必须使用松散的XAML文件。可以使用
System.Windows.Markup.XamlReader.Load(Stream)方法读取松散的XAML文件

Cat.cs:

using System;

namespace WpfCollection._3840371
{
    public class Cat
    {
        public Cat() { }

        public Cat(String name, String color) { Name = name; Color = color; }

        public String Name { get; set; }
        public String Color { get; set; }
    }
}
C室:

using System;
using System.Collections.ObjectModel;

namespace WpfCollection._3840371
{
    public class Room<T> where T : System.Windows.Data.ObjectDataProvider
    {
        public Room()
        {
            Cats = new ObservableCollection<T>();
        }

        public ObservableCollection<T> Cats { get; set; }
    }
}
使用系统;
使用System.Collections.ObjectModel;
命名空间WpfCollection.\u 3840371
{
公共教室,其中T:System.Windows.Data.ObjectDataProvider
{
公共房间()
{
Cats=新的可观察集合();
}
公共可观测集合猫{get;set;}
}
}
窗口类:

namespace WpfCollection._3840371
{
    /// <summary>
    /// Interaction logic for Win3840371.xaml
    /// </summary>
    public partial class Win3840371 : Window
    {
        public Win3840371()
        {
            InitializeComponent();

            Room<ObjectDataProvider> kitchenRoom;
            using (FileStream fs = new FileStream(@"3840371/roomcats.txt", FileMode.Open))
            {
                kitchenRoom = (Room<ObjectDataProvider>)XamlReader.Load(fs);
            }

            foreach (ObjectDataProvider o in kitchenRoom.Cats)
                Debug.WriteLine(((Cat)o.Data).Name + " : " + ((Cat)o.Data).Color);
        }
    }
}
名称空间WpfCollection.\u 3840371
{
/// 
///Win3840371.xaml的交互逻辑
/// 
公共部分类Win3840371:窗口
{
公共Win3840371()
{
初始化组件();
厨房房间;
使用(FileStream fs=newfilestream(@“3840371/roomcats.txt”,FileMode.Open))
{
厨房=(房间)XamlReader.Load(fs);
}
foreach(kitchenRoom.Cats中的ObjectDataProvider o)
Debug.WriteLine(((Cat)o.Data.Name+“:”+((Cat)o.Data.Color);
}
}
}
因此,包含XAML代码的.txt文件是:

<local:Room 
            xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
            xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
            xmlns:System="clr-namespace:System;assembly=mscorlib"
            xmlns:local="clr-namespace:WpfCollection._3840371;assembly=WpfCollection"
            x:Key="UpperRoom" x:TypeArguments="ObjectDataProvider">
            <local:Room.Cats>
                <ObjectDataProvider x:Key="Cat1" ObjectType="{x:Type local:Cat}">
                    <ObjectDataProvider.ConstructorParameters>
                        <System:String>Tom</System:String>
                        <System:String>Red</System:String>
                    </ObjectDataProvider.ConstructorParameters>
                </ObjectDataProvider>
                <ObjectDataProvider x:Key="Cat2" ObjectType="{x:Type local:Cat}">
                    <ObjectDataProvider.ConstructorParameters>
                        <System:String>Rubia</System:String>
                        <System:String>Brown</System:String>
                    </ObjectDataProvider.ConstructorParameters>
                </ObjectDataProvider>
            </local:Room.Cats>
        </local:Room>

汤姆
红色
茜草
棕色的

可以通过将
添加到您的猫列表中来实现这一点。因为我目前无法测试它,所以我只是将其作为注释添加…@Heinzi:我尝试过,它可以编译,但运行时它给出了一个XamlParseException:类型为'System.Windows.Data.ObjectDataProvider'的对象无法转换为'System.Collections.ObjectModel.ObservableCollection'1[Cat]'类型,我明白了。接下来,我将尝试(a)在
内部的XAML中创建一个ObservableCollection(请参阅中的“XAML使用说明”),然后(b)用
Cat
替换
ObjectDataProvider
(即
),然后添加指向ObservableCollection内部Cat的StaticResource。但是,这需要您的
Cat
类具有无参数构造函数。请确保将生成操作设置为Content,并将“复制到输出目录”属性设置为Always for roomcats.txt。
namespace WpfCollection._3840371
{
    /// <summary>
    /// Interaction logic for Win3840371.xaml
    /// </summary>
    public partial class Win3840371 : Window
    {
        public Win3840371()
        {
            InitializeComponent();

            Room<ObjectDataProvider> kitchenRoom;
            using (FileStream fs = new FileStream(@"3840371/roomcats.txt", FileMode.Open))
            {
                kitchenRoom = (Room<ObjectDataProvider>)XamlReader.Load(fs);
            }

            foreach (ObjectDataProvider o in kitchenRoom.Cats)
                Debug.WriteLine(((Cat)o.Data).Name + " : " + ((Cat)o.Data).Color);
        }
    }
}
<local:Room 
            xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
            xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
            xmlns:System="clr-namespace:System;assembly=mscorlib"
            xmlns:local="clr-namespace:WpfCollection._3840371;assembly=WpfCollection"
            x:Key="UpperRoom" x:TypeArguments="ObjectDataProvider">
            <local:Room.Cats>
                <ObjectDataProvider x:Key="Cat1" ObjectType="{x:Type local:Cat}">
                    <ObjectDataProvider.ConstructorParameters>
                        <System:String>Tom</System:String>
                        <System:String>Red</System:String>
                    </ObjectDataProvider.ConstructorParameters>
                </ObjectDataProvider>
                <ObjectDataProvider x:Key="Cat2" ObjectType="{x:Type local:Cat}">
                    <ObjectDataProvider.ConstructorParameters>
                        <System:String>Rubia</System:String>
                        <System:String>Brown</System:String>
                    </ObjectDataProvider.ConstructorParameters>
                </ObjectDataProvider>
            </local:Room.Cats>
        </local:Room>