【问题标题】:Override Standard Theme in App.xaml覆盖 App.xaml 中的标准主题
【发布时间】:2010-12-19 08:16:15
【问题描述】:

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

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

【问题讨论】:

    标签: .net wpf xaml themes


    【解决方案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>
    

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

    【讨论】:

    • 为我工作-但您最好将文本框样式放在单独的资源字典文件(例如 TextBoxStyles.xaml)中,然后将 添加到合并字典。否则,您可能会遇到合并字典的错误,从而导致样式不适用于创建的第一个文本框...
    【解决方案2】:

    我遇到了同样的问题并尝试了 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 文件。

    【讨论】:

      【解决方案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>
      

      【讨论】:

        猜你喜欢
        • 2011-01-23
        • 1970-01-01
        • 2011-04-03
        • 2020-10-24
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多