WPF Разделение стилей, которые зависят от других стилей, в собственный словарь ресурсов

Я работаю над приложением C# MEF/Caliburn.Micro, в котором есть несколько словарей ресурсов для стилей, цветов и т. Д. Я пытаюсь дать каждому стилю отдельный файл, и у меня возникает проблема со стилями, основанными на о стилях в других ресурсных словарях. Все ресурсы приложения находятся в Infastructure проект, который объединяется в App.xaml,

Вот мой макет решения:

Solution

  ->Shell
    App.xaml
    (other shell-related files)

  ->Infastructure
    ->ResourceDictionaries
      ->Brushes
          DefaultColorTheme.xaml
      ->ControlStyles
          ButtonStyle.xaml
          DeleteButtonStyle.xaml
          EditButtonStyle.xaml
      ResourceLibrary.xaml

ResourceLibrary.xaml - это объединение всех словарей ресурсов в папке ResourceDictionaries.

ResourceLibrary.xaml

<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
                xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
<ResourceDictionary.MergedDictionaries>
  <ResourceDictionary Source="Brushes/DefaultColorTheme.xaml"/>
  <ResourceDictionary Source="ControlStyles/ButtonStyle.xaml"/>
  <ResourceDictionary Source="ControlStyles/DeleteButtonStyle.xaml"/>
  <ResourceDictionary Source="ControlStyles/EditButtonStyle.xaml"/>
</ResourceDictionary.MergedDictionaries>
</ResourceDictionary>

ResourceLibrary.xaml объединяется с App.xaml

App.xaml

<Application...
         >
<Application.Resources>
  <ResourceDictionary>
     <ResourceDictionary.MergedDictionaries>
        <ResourceDictionary Source="/Infastructure;component/ResourceDictionaries/ResourceLibrary.xaml"/>
        <ResourceDictionary>
           <local:Bootstrapper x:Key="Bootstrapper"/>
        </ResourceDictionary>
        </ResourceDictionary.MergedDictionaries>
  </ResourceDictionary>
 </Application.Resources>
</Application>

ButtonStyle.xaml содержит мой основной стиль кнопок, предназначенный для ButtonBaseи два анонимных стиля, которые применяют основной стиль кнопки к Button а также ToggleButton

ButtonStyle.xaml

<Style x:Key="ButtonStyle" TargetType="{x:Type ButtonBase}">
  ...
</Style>

<Style BasedOn="{StaticResource ButtonStyle}" TargetType="{x:Type Button}"/>
<Style BasedOn="{StaticResource ButtonStyle}" TargetType="{x:Type ToggleButton}"/>

Это отлично работает. Все Buttonс и ToggleButtonс в стиле применяются.

У меня есть два других стиля кнопок, которые интенсивно используются в приложении, DeleteButtonStyle а также EditButtonStyle, что должно быть основано на ButtonStyle, Вот фрагмент кода из DeleteButtonStyle.xaml. EditButtonStyle аналогичен.

<Style x:Key="DeleteButtonStyle" TargetType="{x:Type ButtonBase}" BasedOn="{StaticResource ButtonStyle}">
 ....
</Style>

Все работает во время разработки. Кнопки получают ButtonStyle стиль и кнопки, помеченные явно ...Style="{DynamicResource DeleteButtonStyle}"... получить DeleteButtonStyle применяется к ним. Однако во время выполнения я всегда получаю следующее исключение:

System.Windows.Markup.XamlParseException occurred
 HResult=-2146233087
 Message='Provide value on 'System.Windows.Markup.StaticResourceHolder' threw an exception.' Line number '4' and line position '35'.
  Source=PresentationFramework
  LineNumber=4
  LinePosition=35
  StackTrace:
    at System.Windows.Markup.WpfXamlLoader.Load(XamlReader xamlReader, IXamlObjectWriterFactory writerFactory, Boolean skipJournaledProperties, Object rootObject, XamlObjectWriterSettings settings, Uri baseUri)
    at System.Windows.Markup.WpfXamlLoader.LoadBaml(XamlReader xamlReader, Boolean skipJournaledProperties, Object rootObject, XamlAccessLevel accessLevel, Uri baseUri)
    at System.Windows.Markup.XamlReader.LoadBaml(Stream stream, ParserContext parserContext, Object parent, Boolean closeStream)
    at System.Windows.Application.LoadComponent(Object component, Uri resourceLocator)
    ...
 InnerException: 
   HResult=-2146233088
   Message=Cannot find resource named 'ButtonStyle'. Resource names are case sensitive.
   Source=PresentationFramework
   StackTrace:
        at System.Windows.StaticResourceExtension.ProvideValueInternal(IServiceProvider serviceProvider, Boolean allowDeferredReference)
        at System.Windows.StaticResourceExtension.ProvideValue(IServiceProvider serviceProvider)
        at MS.Internal.Xaml.Runtime.ClrObjectRuntime.CallProvideValue(MarkupExtension me, IServiceProvider serviceProvider)
   InnerException:

Если я перееду DeleteButtonStyle а также EditButtonStyle в тот же файл, где ButtonStyle есть (ButtonStyle.xaml), вот так

<Style x:Key="ButtonStyle" TargetType="{x:Type ButtonBase}">
  ...
</Style>

<Style BasedOn="{StaticResource ButtonStyle}" TargetType="{x:Type Button}"/>
<Style BasedOn="{StaticResource ButtonStyle}" TargetType="{x:Type ToggleButton}"/>

<Style x:Key="DeleteButtonStyle" TargetType="{x:Type ButtonBase}" BasedOn="{StaticResource ButtonStyle}">
 ....
</Style>
<Style x:Key="EditButtonStyle" TargetType="{x:Type ButtonBase}" BasedOn="{StaticResource ButtonStyle}">
 ....
</Style>

тогда все работает.

Как разделить стили, зависящие от других стилей, в свой словарь ресурсов?

1 ответ

Решение

В вашем DeleteButtonStyle а также EditButtonStyle

  <ResourceDictionary Source="ControlStyles/DeleteButtonStyle.xaml"/>
  <ResourceDictionary Source="ControlStyles/EditButtonStyle.xaml"/>

Вы должны явно объединить ResourceDictionary внутри двух файлов для загрузки ButtonStyle,

Так

<ResourceDictionary>
     <ResourceDictionary.MergedDictionaries>
        <ResourceDictionary Source="/Infastructure;component/ResourceDictionaries/ButtonStyle.xaml"/>
     </ResourceDictionary.MergedDictionaries>
</ResourceDictionary>
Другие вопросы по тегам