2010-11-25 79 views
5

我想下面的樣式應用到從ButtonBase如何將樣式應用於類和它的後代?

<Style 
    TargetType="{x:Type ButtonBase}"> 
    <Setter 
     Property="Cursor" 
     Value="Hand" /> 
</Style> 

獲得的所有控件,但它僅適用於一個給定的類,而不是它的後代。如何實現我的目標?

回答

4

這不起作用,因爲當一個元素沒有風格明確分配,WPF通過調用FindResource,使用元素的類型爲關鍵認定其風格。事實上,您創建的關鍵是ButtonBase的樣式並不重要:WPF使用ButtonToggleButton的關鍵字查找樣式並使用它。

基於繼承的查找方法將使用元素的類型來查找樣式,然後在沒有找到元素類型的樣式的情況下使用基本類型(並繼續前進,直到找到樣式或點擊FrameworkElement) 。問題是,只有在找不到匹配的情況下才有效 - 即,如果Button沒有默認樣式,當然也有。

你可以做兩件事。一個是做Jens建議的,使用樣式的BasedOn屬性來實現你自己的樣式層次結構。儘管如此,這很麻煩,因爲你必須爲每種類型定義一種風格;如果不這樣做,將使用該類型的默認WPF樣式。

另一種方法是使用實​​現此查找行爲的StyleSelector。就像這樣:

public class InheritanceStyleSelector : StyleSelector 
{ 
    public InheritanceStyleSelector() 
    { 
     Styles = new Dictionary<object, Style>(); 
    } 
    public override Style SelectStyle(object item, DependencyObject container) 
    { 
     Type t = item.GetType(); 
     while(true) 
     { 
      if (Styles.ContainsKey(t)) 
      { 
       return Styles[t]; 
      } 
      if (t == typeof(FrameworkElement) || t == typeof(object)) 
      { 
       return null; 
      } 
      t = t.BaseType; 
     } 
    } 

    public Dictionary<object, Style> Styles { get; set; } 
} 

您可以創建這樣一個實例,給它一組樣式,然後把它連接到任何ItemsControl

<Window x:Class="StyleSelectorDemo.MainWindow" 
     xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
     xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:StyleSelectorDemo="clr-namespace:StyleSelectorDemo" Title="MainWindow" Height="350" Width="525"> 
    <Window.Resources> 
     <StyleSelectorDemo:InheritanceStyleSelector x:Key="Selector"> 
      <StyleSelectorDemo:InheritanceStyleSelector.Styles> 
       <Style x:Key="{x:Type ButtonBase}"> 
        <Setter Property="ButtonBase.Background" 
          Value="Red" /> 
       </Style> 
       <Style x:Key="{x:Type ToggleButton}"> 
        <Setter Property="ToggleButton.Background" 
          Value="Yellow" /> 
       </Style> 
      </StyleSelectorDemo:InheritanceStyleSelector.Styles> 
     </StyleSelectorDemo:InheritanceStyleSelector> 
    </Window.Resources> 
    <Grid> 
     <ItemsControl ItemContainerStyleSelector="{StaticResource Selector}"> 
      <Button>This is a regular Button</Button> 
      <ToggleButton>This is a ToggleButton.</ToggleButton> 
      <TextBox>This uses WPF's default style.</TextBox> 
     </ItemsControl> 
    </Grid> 
</Window> 
1

這確實似乎是造型系統的限制。

面對這個問題,我宣佈了一些基本風格,併爲我關心的每一個後代「分」風格。

<Style x:Key="ButtonBaseStyle" TargetType="{x:Type ButtonBase}"> 
    <!-- Style stuff --> 
</Style> 
<Style TargetType="{x:Type Button}" BasedOn="{StaticResource ButtonBaseStyle}"> 
    <!-- Additional style stuff for button only --> 
</Style> 
<Style TargetType="{x:Type ToggleButton}" BasedOn="{StaticResource ButtonBaseStyle}"> 
    <!-- Additional style stuff for toggle button only --> 
</Style> 
<!-- more ButtonBase descendants here --> 
相關問題