覆盖App.xaml中的标准主题

时间:2009-11-23 02:27:11

标签: .net wpf xaml themes

我正在使用标准的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 个答案:

答案 0 :(得分: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>

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

答案 1 :(得分: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文件。

答案 2 :(得分: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>