在 XAML 中实例化和重用对象实例
我想在 XAML 中实例化对象,并重用这些实例。我认为它应该很简单,但我被困住了,我可能错过了一些明显的东西。
假设我想将猫添加到不同的房间(房间有一个包含 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>
在我的 UserControl 中,我想将 Cat 添加到 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>
将 Cat 实例添加到 ObservableCollection Room.Cats 的语法是什么?例如,我想将 Cat1 和 Cat2 添加到 Room1,将 Cat2 和 Cat3 添加到 Room2。我完全走错路了吗?
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?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
按照您尝试的方式重用单个实例是很棘手的。这是因为在 XAML 中引用单个对象的方式通常是使用
StaticResource
标记扩展,并且您只能使用该标记扩展来设置属性值。因此,您可以轻松地将
Cat
类型的属性设置为Cat
的实例:但无法通过设置属性来填充集合。
令人惊讶的是,答案是直接在 XAML 中实例化对象,而不是将它们包装在
ObjectDataProvider
中。您仍然使用ObjectDataProvider
,但有所不同: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 aCat
: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 theObjectDataProvider
, but differently:根据 Heinzi 和 Robert Rossney 的反馈,我提出了以下与 ObservableCollection 配合使用的解决方案,我可以在 XAML 和后面的代码中访问它:
在代码中,我扩展了 ObservableCollection,以便我可以在 XAML 中使用它(这不再是必要的)在 XAML 2009 中):
在 UserControl.Resources 的 XAML 中,我实例化了 Cats:
集合:
房间现在定义如下:
Room.Cats 是一个 ObservableCollection;
Based on the feedback from Heinzi and Robert Rossney I came up with the following solution that works with an ObservableCollection that I can access in XAML and code behind:
In code I extended ObservableCollection so I can use it in XAML (this will no longer be necessary in XAML 2009):
In XAML in the UserControl.Resources I instantiate the Cats:
The collections:
The Rooms are now defined as follows:
Room.Cats is an ObservableCollection<Cat>
对于您非常具体的需求,您应该选择仿制药。要以声明方式使用泛型,您必须使用 x:类型参数指令。 TypeArguments 指令只能与根元素一起使用。因此,您现在必须寻找松散的 XAML 文件。可以使用 System.Windows.Markup.XamlReader.Load(Stream Stream) 方法读取松散的 XAML 文件
Cat.cs :
Room.cs :
Window 类 :
因此,包含 XAML 代码的 .txt 文件将是 :
For your very specific needs, you to do go for generics. And to use generics declaratively, you have to use x:TypeArguments Directive. TypeArguments directive can be used only with root element. So, you have to now go for loose XAML file. A loose XAML file can be read using
System.Windows.Markup.XamlReader.Load(Stream Stream) method
Cat.cs :
Room.cs :
Window class :
So, your .txt file containing XAML code would be :