将默认 Button 样式应用于自定义 Button 类 [英] Apply default Button style to custom Button class

查看:37
本文介绍了将默认 Button 样式应用于自定义 Button 类的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我创建了一个自定义 IconButton 类,该类继承自 Button 并添加了一些依赖属性以将图像放置在按钮文本的前面.

I've created a custom IconButton class that inherits from Button and adds a few dependency properties to place an image in front of the button's text.

代码是这样开始的:

public partial class IconButton : Button
{
    // Dependency properties and other methods
}

它带有一个看起来像这样的 XAML 文件:

It comes with a XAML file that looks like this:

<Button x:Class="Unclassified.UI.IconButton" x:Name="_this" ...>
    <Button.Template>
        <ControlTemplate>
            <Button
                Padding="{TemplateBinding Padding}"
                Style="{TemplateBinding Style}"
                Focusable="{TemplateBinding Focusable}"
                Command="{TemplateBinding Button.Command}">

                <StackPanel ...>
                    <Image .../>
                    <ContentPresenter
                        Visibility="{Binding ContentVisibility, ElementName=_this}"
                        RecognizesAccessKey="True"
                        Content="{Binding Content, ElementName=_this}">
                        <ContentPresenter.Style>
                            ...
                        </ContentPresenter.Style>
                    </ContentPresenter>
                </StackPanel>
            </Button>
        </ControlTemplate>
    </Button.Template>
</Button>

到目前为止效果很好.(但如果您知道一种更简单的方法来覆盖 Button 的内容而不更改整个模板并将 Button 放置在 Button 中,请告诉我.每次我尝试时,Visual Studio 2010 SP1 在我关闭最终的 XML 标记的那一刻立即崩溃.)

That works well so far. (But if you know a simpler way to override a Button's content without changing the entire template and placing a Button within the Button, please let me know. Every time I tried, Visual Studio 2010 SP1 immediately crashed the moment I closed the final XML tag.)

现在我添加了一些代码来修复 Windows 8 的 WPF 损坏的 Aero2 主题.它是一个单独的 ResourceDictionary,可以覆盖各种默认样式:(基于此通过这里)

Now I've added some code to fix WPF's broken Aero2 theme for Windows 8. It's a separate ResourceDictionary that overwrites all sorts of default styles: (Based on this, via here)

<ResourceDictionary ...>
    <Style TargetType="{x:Type Button}">
        ...
    </Style>
</ResourceDictionary>

新的 ResourceDictionary 会在启动时添加到 App.xaml.cs 中的应用程序资源中:

The new ResourceDictionary is added to the Application Resources on startup, in App.xaml.cs:

protected override void OnStartup(StartupEventArgs args)
{
    base.OnStartup(e);
    // Fix WPF's dumb Aero2 theme if we're on Windows 8 or newer
    if (OSInfo.IsWindows8OrNewer)
    {
        Resources.MergedDictionaries.Add(new ResourceDictionary
        {
            Source = new Uri("/Resources/RealWindows8.xaml", UriKind.RelativeOrAbsolute)
        });
    }
    ...
}

这也适用于我放置在 XAML 视图中的普通 Button 控件.(我仍在寻找一种方法来找出真正的 Windows 主题,而不是依赖版本号.)

This also works well for normal Button controls I place in my XAML views. (I'm still looking for a method to find out the real Windows theme instead of relying on the version number.)

但是我的 IconButton 控件没有考虑这些新的默认值,并且仍然基于 WPF 的非常基本的内置按钮样式.(它实际上只是一个紧凑的矩形,没有 Win32 显示的所有细节和交互性.)

But my IconButton control doesn't consider these new defaults and is still based on WPF's built-in Button style which is very basic. (It's really just a tight rectangle without all the details and interactivity that Win32 shows.)

我想我需要一种方法来告诉我的 IconButton 它应该重新评估基本样式并查看新添加的 RealWindows8 样式.我该怎么做?

I guess I need a way to tell my IconButton that it should re-evaluate the base style and see the newly added RealWindows8 styles. How can I do that?

推荐答案

我找到了解决方案.有两种方法可以实现这一点.任何一个都足够了.

I found the solution. There are two ways to accomplish this. Either one is sufficient.

XAML 方式:

将 Style 属性添加到派生控件.这将新控件的样式显式地预设为在应用程序中定义为 Button 样式的任何内容.StaticResource 就足够了.如果在使用派生控件的地方指定了不同的样式,则将替换此初始值.

Add the Style attribute to the derived control. This presets the new control's style explicitly to whatever has been defined in the application as the Button style. StaticResource is sufficient for this. If a different Style is specified where the derived control is used, that will replace this initial value.

<Button Style="{StaticResource {x:Type Button}}" ...>
    ...
</Button>

代码(隐藏)方式:

在派生类的构造函数中调用 SetResourceReference 方法.

Call the SetResourceReference method in the constructor of the derived class.

public IconButton()
{
    // Use the same style as Button, also when it is overwritten by the application.
    SetResourceReference(StyleProperty, typeof(Button));
    ...
}

我已经为我的 IconButton 以及派生的 TabControl 和 TabItem 类测试了这个.

I've tested this for my IconButton as well as a derived TabControl and TabItem class.

(来源)

这篇关于将默认 Button 样式应用于自定义 Button 类的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆