WPF ResourceDictionary Item уже был добавлен с использованием ComponentResourceKey - PullRequest
5 голосов
/ 30 июля 2010

У меня есть следующий ResourceDictionary, который объединяется с моим файлом Themes / 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>

Я пытаюсь создать два разных шаблона данных для одного и того же DataType с разными ComponentResourceKey. Как вы можете видеть, к одному из ключей добавлено 2.

В моем классе Local: Resources у меня есть следующий компонент - ComponentResourceKey, который я использую.

    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 игнорирует ключ при добавлении DataTemplate. Игнорирует ли ResourceDictionary свойство ключа, когда оно использует ComponentRelationKey?

Есть ли способ обойти это исключение?

Спасибо, Raul

Ответы [ 3 ]

9 голосов
/ 07 ноября 2013

Видимо проблема как заявлена, вроде.Порядок объявления стиля имеет значение.

Когда первый атрибут для двух стилей для одного и того же TargetType равен TargetType например,

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

тогда вы получите ошибку.Кажется, он игнорирует атрибут Key: и, как указано, использует значение TargetType в качестве ключа словаря, например, "{x: Type TextBlock}"

Когда первый элемент из двух стилей для одного и того же TargetType это x: ключ , тогда вы этого не сделаете, как показано ниже.

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

Думаю, не имеет значения, переместишь ли ты чушь.В любом случае, всегда начинайте с x: Key , но это действительно глупая ошибка.

5 голосов
/ 30 июля 2010

Если вы ссылаетесь на свой DataTemplate по ключу, не могли бы вы просто пропустить спецификацию DataType?Без DataType = "{x: Type model: RequirementResourceRelation}" (который, очевидно, является ключом для добавляемого элемента), ваш x: Key должен использоваться в качестве ключа.

1 голос
/ 30 ноября 2012

Перемещение DataTemplate (s) внутри элемента <Resources> другого элемента управления.

В Silverlight это работало просто отлично:

<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 без ошибок.

...