【问题标题】:Apply default Button style to custom Button class将默认 Button 样式应用于自定义 Button 类
【发布时间】:2014-11-17 11:51:30
【问题描述】:

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

代码开头是这样的:

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

它带有一个如下所示的 XAML 文件:

<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 标记的那一刻立即崩溃.)

现在我添加了一些代码来修复 WPF 在 Windows 8 上损坏的 Aero2 主题。它是一个单独的 ResourceDictionary,会覆盖各种默认样式:(Based on this, via here)

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

新的 ResourceDictionary 在启动时添加到应用程序资源中,在 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 控件。 (我还在寻找find out the real Windows theme 的方法,而不是依赖版本号。)

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

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

【问题讨论】:

  • 所以你只想要一个里面有图片的按钮?为什么不将图像作为其内容?
  • 有一个图像和一个 ContentPresenter。它同时具有图像和文本,并且可以通过许多不同的方式进行配置。它一个不平凡的控件。和往常一样,我只是不想在这里在一个问题中加载数百行代码。

标签: wpf xaml


【解决方案1】:

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

XAML 方式:

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

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

代码(-behind)方式:

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

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

我已经针对我的 IconButton 以及派生的 TabControl 和 TabItem 类进行了测试。

(Source)

【讨论】:

    猜你喜欢
    • 2014-08-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-09-17
    • 1970-01-01
    相关资源
    最近更新 更多