我想将以下样式应用于从ButtonBase
<Style
TargetType="{x:Type ButtonBase}">
<Setter
Property="Cursor"
Value="Hand" />
</Style>
但它只适用于给定的类,而不适用于它的后代。如何实现我的目标?
答案 0 :(得分:4)
这不起作用,因为当元素没有显式指定样式时,WPF通过调用FindResource
来找到它的样式,使用元素的类型作为键。您创建了一个密钥为ButtonBase
的样式并不重要的事实:WPF会找到密钥为Button
或ToggleButton
的样式并使用它。
基于继承的查找方法将使用元素的类型查找样式,然后在未找到元素类型的样式时使用基类型(并继续运行,直到找到样式或命中{{1 }})。问题是只有在找不到匹配项时才有效 - 即如果FrameworkElement
没有默认样式,那当然就是。
你可以做两件事。一个是做Jens建议的,使用样式的Button
属性来实现自己的样式层次结构。但是,这有点烦人,因为你必须为每一种类型定义一种风格;如果不这样做,将使用该类型的默认WPF样式。
另一种方法是使用实现此查找行为的BasedOn
。像这样:
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
答案 1 :(得分:3)
这确实似乎是造型系统的限制。
面对这个问题,我宣布了一些基本风格,并为我关心的每个后代“子风格”。
<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 -->