如何更改按钮的默认样式而不将 WPF 从 Aero 恢复为 Classic?

发布于 2024-09-02 14:47:53 字数 2210 浏览 2 评论 0原文

我已将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 实际上是在外部定义的。

I've added PresentationFramework.Aero to my App.xaml merged dictionaries, as in...

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

I'm trying to modify the default look of buttons just slightly. I put this style in my ButtonResourceDictionary:

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

All buttons now have the correct padding and bold text, but they look "Classic", not "Aero". How do I fix this style so my buttons all look Aero but also have these minor changes? I would prefer not to have to set the Style property for every button.

Update

I should have mentioned this in the first place, but if I try to use BasedOn, as shown below, I get a StackOverflowException:

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

This would normally work, but not with the Aero dictionaries merged in. If I comment those dictionaries out, the exception disappears.

Update 2

If I add an x:Key attribute and manually set the style, it works properly (Aero style with padding and bold), but as I said, I'd prefer that the style is automatically applied globally to all buttons.

Update 3

I just discovered a new wrinkle. In my app, ButtonResourceDictionary.xaml is placed in a class library (i.e., in an external project). If I move this file to a local folder, everything works fine. So, the problem seems to be a bad interaction caused by referencing various external resource dictionaries. I'm correcting my App.xaml code snippet (above) to reflect that ButtonResourceDictionary is actually defined externally.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

行雁书 2024-09-09 14:47:53

我希望您同时找到了解决方案。对于其他人,这里有一个解决方法,并且这是另一个。我不确定这是否对您的具体情况有帮助(特别是您引用嵌入式资源字典的事实)。

更新

这是我想出的一个解决方案:

<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 样式。 这是一篇精彩的文章,向您展示如何加载来自代码的资源字典(以及框架自动解析的资源字典)。

I hope you've found a solution in the meantime. For everyone else, here is one workaround, and here is another. I am not sure whether this will help for your specific case though (especially the fact that you reference an embedded resource dictionary).

UPDATE

Here's a solution I came up with:

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

Where StaticApplicationResource is a custom MarkupExtension I wrote that simply calls 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;
    }
}

This way I don't have to reference my resource dictionaries outside of my App.xaml file , which is the way I like it :). You can also put more complicated logic in there too, allowing you to resolve the BasedOn style any way you like. Here is an excellent article showing you how to load resource dictionaries (and those that the framework resolves automatically) from code.

高冷爸爸 2024-09-09 14:47:53

根据您的更新,您可以这样做(诚然,它非常丑陋):

<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}" />

Based on your updates, you could do this (admittedly it is hideously ugly):

<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}" />
你在我安 2024-09-09 14:47:53

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

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

Use the BasedOn attribute to inherit the properties from the Aero Style. This should solve your problem.

<Style
  BasedOn="{StaticResource {x:Type Button}}"
  TargetType="{x:Type Button}"> 
    <Setter Property="Padding" Value="3" /> 
    <Setter Property="FontWeight" Value="Bold" /> 
</Style>
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文