2010-11-25 48 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 --> 
相关问题