【发布时间】: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。它同时具有图像和文本,并且可以通过许多不同的方式进行配置。它是一个不平凡的控件。和往常一样,我只是不想在这里在一个问题中加载数百行代码。