覆盖App.xaml中的标准主题

时间:2021-07-09 06:03:36

I am using the standard WPF theme Aero.NormalColor.xaml. And it works very well. However for the whole application, I would like to override the Foreground color of textboxes to red.

我使用标准的WPF主题Aero.NormalColor.xaml。而且效果很好。但是对于整个应用程序,我想将文本框的前景颜色覆盖为红色。

My first try is that

我的第一次尝试是

<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>

Well... all foreground color of textboxes become red. However all textboxes lose the theme style. Yes, I know I should add "BasedOn". My second try is add "BasedOn" in the style tag.

嗯......文本框的所有前景色都变成了红色。但是,所有文本框都会丢失主题样式。是的,我知道我应该添加“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>

Exception is thrown. Same as this WPF : Extend Theme's style - *Exception

抛出异常。与此WPF相同:扩展主题的样式 - *Exception

Eventually, I achieve my goal by this.

最终,我实现了我的目标。

In App.xaml

在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>

And in all windows and user control, I had to explicitly set

在所有窗口和用户控件中,我必须明确设置

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

The above code is copy and paste for many times and it is not easy to maintain. Does anyone know how to achieve my goal by just set foreground to red by one time?

上面的代码多次复制和粘贴,并且不易维护。有人知道如何通过将前景设置为红色一次来实现我的目标吗?

3 个解决方案

#1


2  

I think you can add the Style to a ResourceDictionary and merging that with the Aero theme like this:

我想你可以将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>

This should give ALL your textboxes red foreground color without having to explicitly specify that on each window and user control.

这应该为您的所有文本框提供红色前景色,而不必在每个窗口和用户控件上明确指定。

#2


1  

I had the same problem and tried Oskar's approach. Though, it caused some strange behaviour. Particularly, the styles did not apply to some controls, while applying to other controls of the same type. And I could not find any major differences between these controls.

我遇到了同样的问题并尝试了奥斯卡的方法。虽然,它引起了一些奇怪的行为。特别是,在应用于相同类型的其他控件时,样式不适用于某些控件。我发现这些控件之间没有任何重大差异。

I continued searching for the solution and I found one here: http://social.msdn.microsoft.com/Forums/en-US/wpf/thread/91718816-8674-4ad8-a3c8-ae283bebe224/

我继续寻找解决方案,我在这里找到了一个:http://social.msdn.microsoft.com/Forums/en-US/wpf/thread/91718816-8674-4ad8-a3c8-ae283bebe224/

It is still not perfect and clear, but it works, at least for me.

它仍然不完美和清晰,但它起作用,至少对我而言。

In brief, you can get the idea from the following code:

简而言之,您可以从以下代码中获得想法:

<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>

For maintainability and readability these nested ResourceDictionary objects could go to separate XAML files.

为了可维护性和可读性,这些嵌套的ResourceDictionary对象可以分离XAML文件。

#3


0  

The exact answer for this question is setting all custom style with based on value from static resource of current control. However, some control may not have default style like ListView or ListViewItem.

这个问题的确切答案是根据当前控件的静态资源的值设置所有自定义样式。但是,某些控件可能没有ListView或ListViewItem等默认样式。

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

This style can locate in any kind resource dictionary like window resources, grid resources, textbox resources or external resource dictionary.

此样式可以位于任何类型的资源字典中,如窗口资源,网格资源,文本框资源或外部资源字典。

Finally, you must add resource dictionary theme to your application resources like the following code that I add Aero theme to my application.

最后,您必须将资源字典主题添加到您的应用程序资源,例如我将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>

#1


2  

I think you can add the Style to a ResourceDictionary and merging that with the Aero theme like this:

我想你可以将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>

This should give ALL your textboxes red foreground color without having to explicitly specify that on each window and user control.

这应该为您的所有文本框提供红色前景色,而不必在每个窗口和用户控件上明确指定。

#2


1  

I had the same problem and tried Oskar's approach. Though, it caused some strange behaviour. Particularly, the styles did not apply to some controls, while applying to other controls of the same type. And I could not find any major differences between these controls.

我遇到了同样的问题并尝试了奥斯卡的方法。虽然,它引起了一些奇怪的行为。特别是,在应用于相同类型的其他控件时,样式不适用于某些控件。我发现这些控件之间没有任何重大差异。

I continued searching for the solution and I found one here: http://social.msdn.microsoft.com/Forums/en-US/wpf/thread/91718816-8674-4ad8-a3c8-ae283bebe224/

我继续寻找解决方案,我在这里找到了一个:http://social.msdn.microsoft.com/Forums/en-US/wpf/thread/91718816-8674-4ad8-a3c8-ae283bebe224/

It is still not perfect and clear, but it works, at least for me.

它仍然不完美和清晰,但它起作用,至少对我而言。

In brief, you can get the idea from the following code:

简而言之,您可以从以下代码中获得想法:

<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>

For maintainability and readability these nested ResourceDictionary objects could go to separate XAML files.

为了可维护性和可读性,这些嵌套的ResourceDictionary对象可以分离XAML文件。

#3


0  

The exact answer for this question is setting all custom style with based on value from static resource of current control. However, some control may not have default style like ListView or ListViewItem.

这个问题的确切答案是根据当前控件的静态资源的值设置所有自定义样式。但是,某些控件可能没有ListView或ListViewItem等默认样式。

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

This style can locate in any kind resource dictionary like window resources, grid resources, textbox resources or external resource dictionary.

此样式可以位于任何类型的资源字典中,如窗口资源,网格资源,文本框资源或外部资源字典。

Finally, you must add resource dictionary theme to your application resources like the following code that I add Aero theme to my application.

最后,您必须将资源字典主题添加到您的应用程序资源,例如我将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>