Переопределить стандартную тему в App.xaml

Я использую стандартную тему WPF Aero.NormalColor.xaml. И это работает очень хорошо. Однако для всего приложения я хотел бы переопределить цвет текстовых полей Foreground до красного.

Моя первая попытка заключается в том, что

<Application.Resources>
    <ResourceDictionary>
        <ResourceDictionary.MergedDictionaries>
            <ResourceDictionary
                Source="/PresentationFramework.Aero, Version=3.0.0.0,
               Culture=neutral, PublicKeyToken=31bf3856ad364e35,
               ProcessorArchitecture=MSIL;component/themes/Aero.NormalColor.xaml">
            </ResourceDictionary>
        </ResourceDictionary.MergedDictionaries>
        <Style TargetType="TextBox">
            <Setter Property="Foreground" Value="Red" />
        </Style>
    </ResourceDictionary>
</Application.Resources>

Ну... весь цвет текстовых полей переднего плана становится красным. Однако все текстовые поля теряют стиль темы. Да, я знаю, что я должен добавить "BasedOn". Моя вторая попытка - добавить "BasedOn" в теге стиля.

<Application.Resources>
    <ResourceDictionary>
        <ResourceDictionary.MergedDictionaries>
            <ResourceDictionary
                Source="/PresentationFramework.Aero, Version=3.0.0.0,
               Culture=neutral, PublicKeyToken=31bf3856ad364e35,
               ProcessorArchitecture=MSIL;component/themes/Aero.NormalColor.xaml">
            </ResourceDictionary>
        </ResourceDictionary.MergedDictionaries>
        <Style TargetType="TextBox" BasedOn="{StaticResource {x:Type TextBox}}">
            <Setter Property="Foreground" Value="Red" />
        </Style>
    </ResourceDictionary>
</Application.Resources>

Выбрасывается исключение. То же, что и qaru.site/info/41543/...

В конце концов, я достигаю своей цели.

В App.xaml

<Application.Resources>
    <ResourceDictionary>
        <ResourceDictionary.MergedDictionaries>
            <ResourceDictionary
                Source="/PresentationFramework.Aero, Version=3.0.0.0,
               Culture=neutral, PublicKeyToken=31bf3856ad364e35,
               ProcessorArchitecture=MSIL;component/themes/Aero.NormalColor.xaml">
            </ResourceDictionary>
        </ResourceDictionary.MergedDictionaries>
    </ResourceDictionary>
</Application.Resources>

И во всех окнах и пользовательском управлении мне пришлось явно установить

<UserControl.Resources>
    <Style TargetType="{x:Type TextBox}" BasedOn="{StaticResource {x:Type TextBox}}">
        <Setter Property="Foreground" Value="Red" />
    </Style>
</UserControl.Resources>

Вышеприведенный код копируется и вставляется много раз, и его непросто поддерживать. Кто-нибудь знает, как достичь моей цели, просто установите переднего плана на красный с помощью один раз?

Ответ 1

Я думаю, вы можете добавить Style в ResourceDictionary и слить это с темой Aero следующим образом:

<Application.Resources>
  <ResourceDictionary>
    <ResourceDictionary.MergedDictionaries>
      <ResourceDictionary Source="/PresentationFramework.Aero, Version=3.0.0.0,
        Culture=neutral, PublicKeyToken=31bf3856ad364e35,
        ProcessorArchitecture=MSIL;component/themes/Aero.NormalColor.xaml">
      </ResourceDictionary>

      <!-- Adding the style to a resource dictionary -->
      <ResourceDictionary>
        <Style TargetType="TextBox" BasedOn="{StaticResource {x:Type TextBox}}">
          <Setter Property="Foreground" Value="Red" />
        </Style>
      </ResourceDictionary>

    </ResourceDictionary.MergedDictionaries>
  </ResourceDictionary>
</Application.Resources>

Это должно привести к тому, что ВСЕ ваши текстовые поля будут красным цветом переднего плана, не указывая явно на каждое окно и пользовательское управление.

Ответ 2

У меня была такая же проблема, и я попытался подойти к Оскару. Хотя это вызвало странное поведение. В частности, стили не применяются к некоторым элементам управления, а применяются к другим элементам управления того же типа. И я не мог найти существенных различий между этими элементами управления.

Я продолжал искать решение, и я нашел его здесь: http://social.msdn.microsoft.com/Forums/en-US/wpf/thread/91718816-8674-4ad8-a3c8-ae283bebe224/

Он все еще не идеален и ясен, но он работает, по крайней мере для меня.

Вкратце, вы можете получить идею из следующего кода:

<Application.Resources>
    <ResourceDictionary>
        <ResourceDictionary.MergedDictionaries>
            <ResourceDictionary>
                <ResourceDictionary.MergedDictionaries>
                    <ResourceDictionary Source="/PresentationFramework.Aero, Version=3.0.0.0,
        Culture=neutral, PublicKeyToken=31bf3856ad364e35,
        ProcessorArchitecture=MSIL;component/themes/Aero.NormalColor.xaml" />
                </ResourceDictionary.MergedDictionaries>
                <Style x:Key="ExtendedTextBoxStyle" TargetType="{x:Type TextBox}" BasedOn="{StaticResource {x:Type TextBox}}">
                    <Setter Property="Foreground" Value="Red" />
                </Style>
            </ResourceDictionary>
        </ResourceDictionary.MergedDictionaries>
        <Style TargetType="{x:Type TextBox}" BasedOn="{StaticResource ExtendedTextBoxStyle}" />
    </ResourceDictionary>
</Application.Resources>

Для удобства и удобочитаемости эти вложенные объекты ResourceDictionary могут перейти в отдельные файлы XAML.

Ответ 3

Точный ответ на этот вопрос заключается в настройке всего пользовательского стиля на основе значения из статического ресурса текущего элемента управления. Однако некоторые элементы управления могут не иметь стиль по умолчанию, например ListView или ListViewItem.

<Style TargetType="TextBox" BasedOn="{StaticResource {x:Type TextBox}}">
    <Setter Property="Width" Value="250" />
    <Setter Property="Height" Value="25" />
</Style>

Этот стиль может размещаться в любом ресурсном словаре, таком как ресурсы окна, ресурсы сетки, ресурсы текстовых полей или словарь внешних ресурсов.

Наконец, вы должны добавить тему ресурса словаря к вашим ресурсам приложения, как следующий код, который я добавляю тему Aero в мое приложение.

<Application.Resources>
    <ResourceDictionary>
        <ResourceDictionary.MergedDictionaries>
            <ResourceDictionary Source="/PresentationFramework.Aero, Version=4.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, ProcessorArchitecture=MSIL;component/themes/aero.normalcolor.xaml" />
            <ResourceDictionary Source="/Themes/Default.xaml" />
        </ResourceDictionary.MergedDictionaries>
    </ResourceDictionary>
</Application.Resources>