代码之家  ›  专栏  ›  技术社区  ›  HaxElit

已使用ComponentResourceKey添加了WPF ResourceDictionary项

  •  4
  • HaxElit  · 技术社区  · 14 年前

    我有以下资源字典合并到主题/generic.xaml文件中

    <DataTemplate DataType="{x:Type model:RequirementResourceRelation}" x:Key="{x:Static local:Resources.RequirementResourceRelationListTemplateKey}">
        <Grid>
            <Grid.ColumnDefinitions>
                <ColumnDefinition Width="Auto" />
                <ColumnDefinition Width="Auto" />
                <ColumnDefinition Width="Auto" />
            </Grid.ColumnDefinitions>
            <TextBlock MinWidth="35" HorizontalAlignment="Left" Padding="3,0" Text="{Binding Resource.Name, TargetNullValue=Loading...}" />
            <TextBlock Grid.Column="1" Text="-" />
            <TextBlock Grid.Column="2" MinWidth="35" HorizontalAlignment="Left" Padding="3,0" Text="{Binding Path=RelationType, TargetNullValue=Loading...}" TextWrapping="NoWrap" TextTrimming="CharacterEllipsis" />
        </Grid>
    </DataTemplate>
    
    <DataTemplate DataType="{x:Type model:RequirementResourceRelation}" x:Key="{x:Static local:Resources.RequirementResourceRelationListTemplate2Key}">
        <Grid>
            <Grid.ColumnDefinitions>
                <ColumnDefinition Width="Auto" />
                <ColumnDefinition Width="Auto" />
                <ColumnDefinition Width="Auto" />
            </Grid.ColumnDefinitions>
            <TextBlock MinWidth="35" HorizontalAlignment="Left" Padding="3,0" Text="{Binding Requirement.Name, TargetNullValue=Loading...}" />
            <TextBlock Grid.Column="1" Text="-" />
            <TextBlock Grid.Column="2" MinWidth="35" HorizontalAlignment="Left" Padding="3,0" Text="{Binding Path=RelationType, TargetNullValue=Loading...}" TextWrapping="NoWrap" TextTrimming="CharacterEllipsis" />
        </Grid>
    </DataTemplate>
    

    我试图为具有不同组件资源的同一数据类型创建两个不同的数据模板。如您所见,其中一个键附加了一个2。

    在我的local:resources类中,我使用了以下组件资源。

        public static ComponentResourceKey RequirementResourceRelationListTemplateKey {
            get {
                return new ComponentResourceKey(typeof(Resources), "RequirementResourceRelationListTemplate");
            }
        }
    
        public static ComponentResourceKey RequirementResourceRelationListTemplate2Key {
            get {
                return new ComponentResourceKey(typeof(Resources), "RequirementResourceRelationListTemplate2");
            }
        }
    

    如果我在其中只有一个数据模板,这是可行的,但是一旦我添加了第二个,就会得到一个异常,它说:

    Item has already been added. Key in dictionary: 'DataTemplateKey(HR.TrackingTool.Model.RequirementResourceRelation)'  Key being added: 'DataTemplateKey(HR.TrackingTool.Model.RequirementResourceRelation)'
       at System.Collections.Hashtable.Insert(Object key, Object nvalue, Boolean add)
       at System.Collections.Hashtable.Add(Object key, Object value)
       at System.Windows.ResourceDictionary.SetKeys(IList`1 keyCollection, IServiceProvider serviceProvider)
       at System.Windows.ResourceDictionary.SetDeferrableContent(DeferrableContent deferrableContent)
       at System.Windows.Baml2006.WpfSharedBamlSchemaContext.<Create_BamlProperty_ResourceDictionary_DeferrableContent>b__168(Object target, Object value)
       at System.Windows.Baml2006.WpfKnownMemberInvoker.SetValue(Object instance, Object value)
       at MS.Internal.Xaml.Runtime.ClrObjectRuntime.SetValue(XamlMember member, Object obj, Object value)
       at MS.Internal.Xaml.Runtime.ClrObjectRuntime.SetValue(Object inst, XamlMember property, Object value)
    

    似乎ResourceDictionary在添加数据模板时忽略了键。ResourceDictionary在使用ComponentRelationKey时是否忽略Key属性?

    有没有办法解决这个例外?

    谢谢, 劳尔

    3 回复  |  直到 11 年前
        1
  •  4
  •   Simon D.    14 年前

    如果您通过键引用您的数据模板,您就不能省略数据类型规范吗? 没有 datatype=“x:类型模型:RequirementResourceRelation” (这显然是添加项的键)您的x:键应用作键。

        2
  •  9
  •   Allen    11 年前

    显然,这个问题是如前所述的,有点像。样式声明的顺序很重要。

    当两个样式的第一个属性相同时 目标类型 目标类型 例如

    <Style TargetType="{x:Type TextBlock}" x:Key="_defaultRuleTextBlockStyle">
    <Style TargetType="{x:Type TextBlock}" x:Key="_tinySourceCodeTextBlockStyle">
    

    然后你就会得到错误。它似乎忽略了key:attribute,如前所述,使用targetType值作为字典键,例如“x:type textblock”

    当两种样式的第一个元素相同时 目标类型 X键 ,则您不会,如下所示。

    <Style x:Key="_defaultRuleTextBlockStyle" TargetType="{x:Type TextBlock}">
    <Style x:Key="_tinySourceCodeTextBlockStyle" TargetType="{x:Type TextBlock}">
    

    我想你把垃圾搬走没关系。对智者说的话,总是从 X键 但这是一个非常愚蠢的错误。

        3
  •  1
  •   Martin Lottering    11 年前

    移动 DataTemplate (S)内部 <Resources> 其他控件的元素。

    银光 这很管用:

    <ResourceDictionary     
                xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
              xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
                     >
        <!--Template 1-->
        <DataTemplate DataType="VMType" x:Key="Template1">
            ...
        </DataTemplate>
        <!--Template 2-->
        <DataTemplate DataType="VMType" x:Key="Template2">
            ...
        </DataTemplate>
        <!--Control Style, references the two templates above-->
        <Style TargetType="ControlType">
            <Setter Property="Template">
                <Setter.Value>
                    <ControlTemplate TargetType="ControlType">
                        <Grid Background="White" Margin="0">          
                            ...
                        </Grid>
                    </ControlTemplate>
                </Setter.Value>
            </Setter>
        </Style>
    </ResourceDictionary>
    

    但在 WPF ,我必须在控件内移动3个模板:

    <ResourceDictionary     
                xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
              xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
                     >
        <Style TargetType="ControlType">
            <Setter Property="Template">
                <Setter.Value>
                    <ControlTemplate TargetType="ControlType">
                        <Grid Background="White" Margin="0">          
                            <!--MOVED HERE INSTEAD OF THE ROOT-->              
                            <Grid.Resources>
                                <!--Template 1-->
                                <DataTemplate DataType="VMType" x:Key="Template1">
                                    ...
                                </DataTemplate>
                                <!--Template 2-->
                                <DataTemplate DataType="VMType" x:Key="Template2">
                                    ...
                                </DataTemplate>
                            </Grid.Resources>
                            ...
                        </Grid>
                    </ControlTemplate>
                </Setter.Value>
            </Setter>
        </Style>
    </ResourceDictionary>
    

    现在它在WPF和Silverlight中都能正常工作,而不会出现错误。

    推荐文章