如果没有WPF从Aero恢复到Classic,如何更改按钮的默认样式?

时间:2010-05-25 02:45:09

标签: wpf xaml themes

我已将PresentationFramework.Aero添加到我的App.xaml合并词典中,如...

<Application
    x:Class="TestApp.App"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
    <Application.Resources>
        <ResourceDictionary>
            <ResourceDictionary.MergedDictionaries>
                <ResourceDictionary
                    Source="/PresentationFramework.Aero;component/themes/Aero.NormalColor.xaml" />
                <ResourceDictionary
                     Source="pack://application:,,,/WPFToolkit;component/Themes/Aero.NormalColor.xaml" />
                <ResourceDictionary
                    Source="/CommonLibraryWpf;component/ResourceDictionaries/ButtonResourceDictionary.xaml" />
                    <!-- Note, ButtonResourceDictionary.xaml is defined in an external class library-->
            </ResourceDictionary.MergedDictionaries>
        </ResourceDictionary>
    </Application.Resources>
</Application>

我正在尝试稍微修改按钮的默认外观。我把这个样式放在我的ButtonResourceDictionary中:

<Style TargetType="Button">
    <Setter Property="Padding" Value="3" />
    <Setter Property="FontWeight" Value="Bold" />
</Style>

所有按钮现在都有正确的填充和粗体文本,但它们看起来是“经典”,而不是“Aero”。如何修复此样式,以便我的按钮看起来都是Aero,但也有这些微小的变化?我宁愿不必为每个按钮设置Style属性。

更新

我应该首先提到这一点,但如果我尝试使用BasedOn,如下所示,我会得到StackOverflowException

<Style BasedOn="{StaticResource {x:Type Button}}" TargetType="{x:Type Button}">
    <Setter Property="Padding" Value="3" />
    <Setter Property="FontWeight" Value="Bold" />
</Style>

这通常会有效,但不会合并到Aero词典中。如果我对这些词典进行评论,则异常会消失。

更新2

如果我添加x:Key属性并手动设置样式,它可以正常工作(带填充和粗体的Aero样式),但正如我所说,我更喜欢将样式全局自动应用于所有按钮

更新3

我刚刚发现了一种新的皱纹。在我的应用程序中,ButtonResourceDictionary.xaml被放置在类库中(即,在外部项目中)。如果我将此文件移动到本地文件夹,一切正常。因此,问题似乎是引用各种外部资源字典引起的不良交互。我正在纠正我的App.xaml代码片段(上面),以反映ButtonResourceDictionary实际上是在外部定义的。

3 个答案:

答案 0 :(得分:8)

我希望你在此期间找到了解决方案。对于其他人,here is one解决方法和here is another。我不确定这是否会对您的特定情况有所帮助(尤其是您引用嵌入式资源字典的事实)。

<强>更新

这是我提出的解决方案:

<Style TargetType="TextBox" BasedOn="{Common:StaticApplicationResource {x:Type TextBox}}">
    <Setter Property="Height" Value="21"/>
</Style>

StaticApplicationResource是自定义MarkupExtension,我写的只是调用TryFindResource

[MarkupExtensionReturnType(typeof(object))]
public class StaticApplicationResource : MarkupExtension
{
    public StaticApplicationResource(object pResourceKey)
    {
        mResourceKey = pResourceKey;
    }

    private object _ResourceKey;

    [ConstructorArgument("pResourceKey")]
    public object mResourceKey
    {
        get { return _ResourceKey; }
        set { _ResourceKey = value; }
    }

    public override object ProvideValue(IServiceProvider serviceProvider)
    {
        if (mResourceKey == null)
            return null;

        object o = Application.Current.TryFindResource(mResourceKey);

        return o;
    }
}

这样我就不必在我的App.xaml文件之外引用我的资源字典了,这就是我喜欢的方式:)。您也可以在其中放置更复杂的逻辑,允许您以任何方式解析BasedOn样式。 Here is an excellent article向您展示如何从代码中加载资源字典(以及框架自动解析的字典)。

答案 1 :(得分:0)

使用BasedOn属性从Aero Style继承属性。这应该可以解决你的问题。

<Style
  BasedOn="{StaticResource {x:Type Button}}"
  TargetType="{x:Type Button}"> 
    <Setter Property="Padding" Value="3" /> 
    <Setter Property="FontWeight" Value="Bold" /> 
</Style>

答案 2 :(得分:0)

根据您的更新,您可以这样做(不可否认它很丑陋):

<Style x:Key="_buttonStyleBase"
       BasedOn="{StaticResource {x:Type Button}}"
       TargetType="{x:Type Button}"> 
    <Setter Property="Padding" Value="3" /> 
    <Setter Property="FontWeight" Value="Bold" /> 
</Style>

<Style TargetType="{x:Type Button}"
       BasedOn="{StaticResource _buttonStyleBase}" />