简体   繁体   English

覆盖App.xaml中的标准主题

[英]Override Standard Theme in App.xaml

I am using the standard WPF theme Aero.NormalColor.xaml. 我正在使用标准的WPF主题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. 但是,对于整个应用程序 ,我想将文本框的前景颜色覆盖为红色。

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". 是的,我知道我应该添加“ BasedOn”。 My second try is add "BasedOn" in the style tag. 我的第二次尝试是在样式标签中添加“ 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 - StackOverflowException 与此WPF相同:扩展主题的样式-StackOverflowException

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 ? 有谁知道如何通过将前景设置为红色一次来实现我的目标?

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. 这应该为您的所有文本框提供红色前景色,而不必在每个窗口和用户控件上明确指定该颜色。

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文件。

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>

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM