2014-11-17 188 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