Основывать стиль на другой стиль в ресурсном словаре

У меня есть тема, которая применяется ко всем кнопкам в словаре ресурсов. Теперь я хочу добавить триггер к кнопке, наследуя изменения стиля из словаря. Я попробовал следующий код:

но он говорит, что элемент управления не может быть найден. Как я могу это исправить?

<UserControl.Resources>
  <ResourceDictionary>
      <ResourceDictionary.MergedDictionaries>
          <ResourceDictionary Source="Theme.xaml"/>
      </ResourceDictionary.MergedDictionaries>

      <conv:ErrorContentConverter x:Key="ErrorContentConverter" />

      <Style x:Key="ValidTrigger" 
             TargetType="Control" BasedOn="{StaticResource {x:Type Control}}" >
         <Style.Triggers>
            <DataTrigger Binding="{Binding Path=IsValid}" Value="False">
              <Setter Property="IsEnabled" Value="false" />
            </DataTrigger>
         </Style.Triggers>
      </Style>   
  </ResourceDictionary>
</UserControl.Resources>

и базовый шаблон:

    <Style TargetType="{x:Type Button}" BasedOn="{x:Null}">
    <Setter Property="FocusVisualStyle" 
            Value="{DynamicResource NuclearButtonFocusVisual}" />
    <Setter Property="Foreground" Value="#FF042271" />
    <Setter Property="FontFamily" Value="Trebuchet MS" />
    <Setter Property="FontSize" Value="12" />
    <Setter Property="Padding" Value="3" />

    <Setter Property="Template" Value="{DynamicResource ButtonTemplate}" />
</Style>

Ответ 1

Дайте вашей базе имя стиля, скажем, FooStyle.

В приведенном вами примере измените TargetType и BasedOn следующим образом:

 <Style x:Key="ValidTrigger" 
        TargetType="{x:Type Control}" BasedOn="{StaticResource {x:Type Control}}" >
    <Style.Triggers>
        <DataTrigger Binding="{Binding Path=IsValid}" Value="False">
            <Setter Property="IsEnabled" Value="false" />
        </DataTrigger>
    </Style.Triggers>
</Style>

Ответ 2

Один трюк, который я использовал в прошлом: в ResourceDictionary, который определяет стили для вашего приложения, добавьте x:Key к стилю, который вы хотели бы наследовать, например:

<Style TargetType="{x:Type Button}" x:Key="ButtonStyle">
  <!-- your style here -->
</Style>

Чтобы применить этот стиль ко всем элементам управления указанного типа (Button в этом примере) без необходимости явно устанавливать атрибут Style для каждого Button, добавьте еще один стиль, который BasedOn этот стиль, но doesn У вас есть ключ:

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

Используя этот метод, все Button в вашем приложении автоматически наследуют ваш собственный стиль, но вы все равно можете создать дополнительные стили BasedOn ButtonStyle и не удалять весь свой пользовательский стиль.

Ответ 3

Я думаю, что для "управления" не существует базового стиля, поэтому ваш BasedOn="{StaticResource {x:Type Control}}" часть ничего не найдет.

Возможно, вы захотите изменить

<Style x:Key="ValidTrigger" TargetType="Control" BasedOn="{StaticResource {x:Type Control}}" >

к

<Style x:Key="ValidTrigger" TargetType="Button" BasedOn="{StaticResource {x:Type Button}}" >

Ответ 4

StaticResource vs DynamicResource

Вместо StaticResource вы хотите использовать DynamicResource. Ваше приложение будет компилироваться, и ресурс будет разрешен во время выполнения вместо компиляции. Раньше считалось, что DynamicResource будет иметь большую стоимость производительности в старые WPF-дни, но теперь это не проблема. Я имею в виду, черт возьми, Expression Blend написан в WPF и использует DynamicResources по всему.


P.S. Имейте в виду, что если вы фактически не определяете имя ресурса, ваше приложение все равно будет работать, но в вашем случае вы потеряете функциональность.:)