2014-11-17 118 views
1

我已经创建了一个自定义的IconButton类,它从Button继承并添加了一些依赖项属性以将按钮的文本放置在图像前面。将默认按钮样式应用于自定义按钮类

的代码是这样开始的:

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的破Aero2主题为Windows 8这是一个单独的ResourceDictionary是覆盖各种默认样式:(Based on thisvia 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视图中放置的普通按钮控件。 (我仍然在寻找一种方法find out the real Windows theme而不是依靠版本号。)

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

我想我需要一种方法告诉我的IconButton它应该重新评估基础样式并查看新添加的RealWindows8样式。我怎样才能做到这一点?

+0

所以你只是想要一个带有图像的按钮?为什么不把图像作为内容? –

+0

有一个图像和一个ContentPresenter。它具有图像和文字两种功能,并且可以通过多种不同的方式进行配置。它是一个不平凡的控制。和往常一样,我只是不想在这里加载数百行代码。 – ygoe

回答

1

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

的XAML方式:

样式属性添加到导出的控制。这会将新控件的样式明确地预设为按照样式在应用程序中定义的任何样式。 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