这不起作用,因为当元素没有显式指定样式时,WPF通过调用
FindResource
,使用元素的类型作为键。你已经创建了一个样式,它的键是
ButtonBase
无所谓:WPF找到键为
Button
或
ToggleButton
使用它。
基于继承的查找方法将使用元素的类型查找样式,如果找不到元素类型的样式,则使用基类型(并继续进行,直到找到样式或命中
FrameworkElement
). 问题是,只有在找不到匹配项时才起作用-即,如果没有
按钮
,当然有。
你可以做两件事。一是按照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>