在App.xaml中覆盖标准主题

8

我正在使用标准的WPF主题Aero.NormalColor.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>
        <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>

抛出异常。与此WPF : Extend Theme's style - StackOverflowException相同。

最终,我通过以下方式实现了我的目标。

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

以上代码需要复制粘贴多次,维护不易。有没有人知道如何只需一次设置前景色为红色来实现我的目标?

3个回答

2
我认为您可以将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>

这将使所有文本框具有红色前景色,而无需在每个窗口和用户控件上显式指定。请注意保留HTML标签。

对我来说有效,但你最好将文本框样式放在单独的资源字典文件中(例如TextBoxStyles.xaml),并只需将<ResourceDictionary Source="TextBoxStyles.xmal"/>添加到合并的字典中。否则,您可能会遇到合并字典中的错误,导致样式未应用于创建的第一个文本框... - Schweder

1

我遇到了同样的问题,并尝试过Oskar的方法。然而,它导致了一些奇怪的行为。特别是,样式未应用于某些控件,同时应用于相同类型的其他控件。我找不到这些控件之间的任何主要区别。

我继续寻找解决方案,在这里找到了一个: 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文件中。

0
这个问题的确切答案是根据当前控件的静态资源值设置所有自定义样式。然而,一些控件可能没有默认样式,比如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>

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接