XAML - Collection Initializers中的StaticResources

时间:2008-12-10 20:53:24

标签: wpf xaml observablecollection static-resource

我想在XAML中添加一个已经实例化一次的模型对象,并将其添加到两个不同的集合中(在xaml中)。

以下代码在Blend的设计时可以很好地呈现,但是我在运行时遇到以下错误:

对于“Post1”
'WpfBlog.Models.Tag'类型的对象无法转换为'System.Collections.ObjectModel.ObservableCollection`1 [WpfBlog.Models.Tag]'类型。标记文件'WpfBlog; component / Admin.xaml'中的对象'WpfBlog.Admin'出错'第XX行位置YY。

如果我注释掉“Post1”,我会在“Post2”上收到此错误
无法将元素添加到属性“Tags”,因为如果属性使用显式集合标记,则该属性只能有一个子元素。标记文件'WpfBlog; component / Admin.xaml'中的对象'System.Windows.StaticResourceExtension'出错'AA行位置BB。

<Window.Resources>
    <model:Tag x:Key="TDD" Name="TDD" ForeColor="Black" BackColor="White" />
    <model:Tag x:Key="Agile" Name="Agile" ForeColor="White" BackColor="Black" />
    <model:Tag x:Key="Waterfail" Name="Waterfail" ForeColor="Red" BackColor="White" />
</Window.Resources>
<Window.DataContext>
    <local:AdminViewModel>
        <local:AdminViewModel.AllTags>
            <StaticResource ResourceKey="TDD"/>
            <StaticResource ResourceKey="Agile"/>
            <StaticResource ResourceKey="Waterfail"/>
        </local:AdminViewModel.AllTags>
        <local:AdminViewModel.Posts>
            <local:PostViewModel Title="Post1">
                <local:PostViewModel.Tags>
                    <StaticResource ResourceKey="TDD" />
                </local:PostViewModel.Tags>
            </local:PostViewModel>
            <local:PostViewModel Title="Post2">
                <local:PostViewModel.Tags>
                    <StaticResource ResourceKey="TDD" />
                    <StaticResource ResourceKey="Agile" />
                    <StaticResource ResourceKey="Waterfail" />
                </local:PostViewModel.Tags>
            </local:PostViewModel>
        </local:AdminViewModel.Posts>
    </local:AdminViewModel>
<Window.DataContext>

以下代码编译并运行正常,但是创建了两个名为“TDD”的标签,因此如果我尝试重命名标签,我必须为所有帖子而不是仅仅一个Tag对象执行此操作。 / p>

<Window.Resources>
    <model:Tag x:Key="TDD" Name="TDD" ForeColor="Black" BackColor="White" />
    <model:Tag x:Key="Agile" Name="Agile" ForeColor="White" BackColor="Black" />
    <model:Tag x:Key="Waterfail" Name="Waterfail" ForeColor="Red" BackColor="White" />
</Window.Resources>
<Window.DataContext>
    <local:AdminViewModel>
        <local:AdminViewModel.AllTags>
            <StaticResource ResourceKey="TDD"/>
            <StaticResource ResourceKey="Agile"/>
            <StaticResource ResourceKey="Waterfail"/>
        </local:AdminViewModel.AllTags>
        <local:AdminViewModel.Posts>
            <local:PostViewModel Title="Post1">
                <local:PostViewModel.Tags>
                    <model:Tag Name="TDD" ForeColor="Black" BackColor="White" />
                </local:PostViewModel.Tags>
            </local:PostViewModel>
            <local:PostViewModel Title="Post2">
                <local:PostViewModel.Tags>
                    <model:Tag Name="TDD" ForeColor="Black" BackColor="White" />
                    <model:Tag Name="Agile" ForeColor="White" BackColor="Black" />
                    <model:Tag Name="Waterfail" ForeColor="Red" BackColor="White" />
                </local:PostViewModel.Tags>
            </local:PostViewModel>
        </local:AdminViewModel.Posts>
    </local:AdminViewModel>
<Window.DataContext>

有什么想法吗?如果Blend没有正确渲染它,我可以忽略它并解决它,但确实如此!

2 个答案:

答案 0 :(得分:4)

我能够通过在Tags属性中显式初始化新集合来避免此问题。像这样:

<local:PostViewModel Title="Post1">
  <local:PostViewModel.Tags>
     <model:TagCollection>
        <StaticResource ResourceKey="TDD" />
     </model:TagCollection>
  </local:PostViewModel.Tags>

显然,只有在允许您的Tags属性可写时才可以这样做。

答案 1 :(得分:0)

这与this question中描述的问题非常相似,我认为。

解决方案应该是向您的&lt; model:Tag&gt;添加x:Shared =“False”属性。元素。这告诉WPF每次引用一个实例时都不要共享一个实例,而是创建它们的新实例。