Как объединить импортированные и локальные ресурсы в пользовательском элементе управления WPF

82

Я пишу несколько пользовательских элементов управления WPF, которым нужны как общие, так и индивидуальные ресурсы.

Я разобрался с синтаксисом загрузки ресурсов из отдельного файла ресурсов:

<UserControl.Resources>
    <ResourceDictionary Source="ViewResources.xaml" />
</UserControl.Resources>

Однако когда я это делаю, я не могу добавлять ресурсы локально, например:

<UserControl.Resources>
    <ResourceDictionary Source="ViewResources.xaml" />
    <!-- Doesn't work: -->
    <ControlTemplate x:Key="validationTemplate">
        ...
    </ControlTemplate>
    <style x:key="textBoxWithError" TargetType="{x:Type TextBox}">
        ...
    </style>
    ...
</UserControl.Resources>

Я посмотрел ResourceDictionary.MergedDictionaries, но это позволяет мне только объединить более одного внешнего словаря, но не определять дополнительные ресурсы локально.

Я, должно быть, упускаю что-то тривиальное?

Следует отметить: я размещаю свои пользовательские элементы управления в проекте WinForms, поэтому размещение общих ресурсов в App.xaml на самом деле не вариант.

Тор Хауген
источник

Ответы:

157

Я понял. Решение включает в себя MergedDictionaries, но специфика должна быть правильной, например:

<UserControl.Resources>
    <ResourceDictionary>
        <ResourceDictionary.MergedDictionaries>
            <ResourceDictionary Source="ViewResources.xaml" />
        </ResourceDictionary.MergedDictionaries>
        <!-- This works: -->
        <ControlTemplate x:Key="validationTemplate">
            ...
        </ControlTemplate>
        <style x:key="textBoxWithError" TargetType="{x:Type TextBox}">
            ...
        </style>
        ...
    </ResourceDictionary>
</UserControl.Resources>

То есть локальные ресурсы должны быть вложены в тег ResourceDictionary. Так что приведенный здесь пример неверен.

Тор Хауген
источник
5

Вы можете определить локальные ресурсы в разделе MergedDictionaries:

<UserControl.Resources>
    <ResourceDictionary>
        <ResourceDictionary.MergedDictionaries>
            <!-- import resources from external files -->
            <ResourceDictionary Source="ViewResources.xaml" />

            <ResourceDictionary>
                <!-- put local resources here -->
                <Style x:key="textBoxWithError" TargetType="{x:Type TextBox}">
                    ...
                </Style>
                ...
            </ResourceDictionary>
        </ResourceDictionary.MergedDictionaries>
    </ResourceDictionary>
</UserControl.Resources>
Lu55
источник
5

Используйте MergedDictionaries .

Отсюда я получил следующий пример .

Файл1

<ResourceDictionary 
  xmlns=" http://schemas.microsoft.com/winfx/2006/xaml/presentation "
  xmlns:x=" http://schemas.microsoft.com/winfx/2006/xaml " > 
  <Style TargetType="{x:Type TextBlock}" x:Key="TextStyle">
    <Setter Property="FontFamily" Value="Lucida Sans" />
    <Setter Property="FontSize" Value="22" />
    <Setter Property="Foreground" Value="#58290A" />
  </Style>
</ResourceDictionary>

Файл 2

   <ResourceDictionary>
        <ResourceDictionary.MergedDictionaries>
          <ResourceDictionary Source="TextStyle.xaml" />
        </ResourceDictionary.MergedDictionaries>
      </ResourceDictionary> 
Preet Sangha
источник
Спасибо, но не повезло. Его пример кажется правильным, но на самом деле не работает. Я получаю сообщение «Свойство« Ресурсы »установлено более одного раза».
Тор Хауген,
Я знаю про MergedDictionaries. Но они не позволяют мне комбинировать ссылку на внешний словарь с локально определенными ресурсами так, как я хочу. Как уже говорилось, на странице, на которую вы ссылаетесь, есть пример, но он не работает.
Тор Хауген,
2
Для тех, кто получает эту ошибку «установить более одного раза»: все остальные ресурсы должны находиться в пределах первого тега <ResourceDictionary>.
Hexo