WPF 绑定到触发器中样式目标上的 属性
WPF Bind to a property on the Style's target in Trigger
我想在 Button
中添加一个 GeometryDrawing
,当鼠标悬停在 Button
:
上时,它会改变它的 Geometry
<Style TargetType="{x:Type Button}">
<Setter Property="Content">
<Setter.Value>
<Rectangle>
<Rectangle.Fill>
<DrawingBrush>
<DrawingBrush.Drawing>
<DrawingGroup>
<DrawingGroup.Children>
<!-- This Binding works -->
<GeometryDrawing Brush="{Binding Foreground, RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type Button}}}"
Geometry="M8,8 1,8 1,3 8,3z M9,9 0,9 0,0 9,0z" />
</DrawingGroup.Children>
</DrawingGroup>
</DrawingBrush.Drawing>
</DrawingBrush>
</Rectangle.Fill>
</Rectangle>
</Setter.Value>
</Setter>
<Style.Triggers>
<Trigger Property="IsMouseOver" Value="True">
<Setter Property="Content">
<Setter.Value>
<Rectangle>
<Rectangle.Fill>
<DrawingBrush>
<DrawingBrush.Drawing>
<DrawingGroup>
<DrawingGroup.Children>
<!-- This Binding does not work -->
<GeometryDrawing Brush="{Binding Foreground, RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type Button}}}"
Geometry="M6,9 1,9 1,5 6,5z M7,10 0,10 0,3 7,3z M10,7 7,7 7,6 9,6 9,2 4,2 4,3 3,3 3,0 10,0z" />
</DrawingGroup.Children>
</DrawingGroup>
</DrawingBrush.Drawing>
</DrawingBrush>
</Rectangle.Fill>
</Rectangle>
</Setter.Value>
</Setter>
</Trigger>
</Style.Triggers>
</Style>
但是,它给了我这个错误
System.Windows.Data Error: 4 : Cannot find source for binding with reference 'RelativeSource FindAncestor, AncestorType='System.Windows.Controls.Button', AncestorLevel='1''.
我不知道为什么,因为 Binding 在 Style
的 Setter
中有效 ,但在 Style
中无效]的Trigger
的Setter
.
我不知道为什么它在后者中不起作用或如何解决它。
非常感谢任何帮助!
编辑:
我也尝试了 {TemplateBinding Button.Foreground}
和 {RelativeSource = {RelativeSource TemplatedParent}}
,它们都不起作用,所以现在的问题是:如何绑定到 Style
上的 属性的目标在 Trigger
?
将 Content
从 Style
更改为 Setters
和 Triggers
是不好的做法,它允许样式缓存元素和使用相同元素的各种问题您的情况下多个按钮的内容,这在 wpf 中是不允许的。
Triggers
中的 Binding
无法工作,因为它在创建时与按钮不在同一可视化树中。这就是数据错误告诉您的内容。
你真正想要的是改变按钮的ControlTemplate
。不同之处在于 ControlTemplate
中的新元素是为具有此样式的每个按钮创建的。
控件模板示例:
<ControlTemplate x:Key="ButtonBaseControlTemplate1" TargetType="{x:Type ButtonBase}">
<Border x:Name="border" BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="{TemplateBinding BorderThickness}" Background="{TemplateBinding Background}" SnapsToDevicePixels="True">
<Grid>
<Rectangle x:Name="normalIcon">
//same as before
</Rectangle>
<Rectangle x:Name="mouseOverIcon" Visibility="Collapsed">
//same as before
</Rectangle>
<ContentPresenter x:Name="contentPresenter" ContentTemplate="{TemplateBinding ContentTemplate}" Content="{TemplateBinding Content}" ContentStringFormat="{TemplateBinding ContentStringFormat}" Focusable="False" HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}" Margin="{TemplateBinding Padding}" RecognizesAccessKey="True" SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}" VerticalAlignment="{TemplateBinding VerticalContentAlignment}"/>
</Grid>
</Border>
<ControlTemplate.Triggers>
//other triggers from default template
<Trigger Property="IsMouseOver" Value="True">
<Setter Property="Background" TargetName="border" Value="#FFBEE6FD"/>
<Setter Property="BorderBrush" TargetName="border" Value="#FF3C7FB1"/>
<Setter Property="Visibility" TargetName="normalIcon" Value="Collapsed"/>
<Setter Property="Visibility" TargetName="mouseOverIcon" Value="Visible"/>
</Trigger>
//other triggers from default template
</ControlTemplate.Triggers>
我想在 Button
中添加一个 GeometryDrawing
,当鼠标悬停在 Button
:
Geometry
<Style TargetType="{x:Type Button}">
<Setter Property="Content">
<Setter.Value>
<Rectangle>
<Rectangle.Fill>
<DrawingBrush>
<DrawingBrush.Drawing>
<DrawingGroup>
<DrawingGroup.Children>
<!-- This Binding works -->
<GeometryDrawing Brush="{Binding Foreground, RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type Button}}}"
Geometry="M8,8 1,8 1,3 8,3z M9,9 0,9 0,0 9,0z" />
</DrawingGroup.Children>
</DrawingGroup>
</DrawingBrush.Drawing>
</DrawingBrush>
</Rectangle.Fill>
</Rectangle>
</Setter.Value>
</Setter>
<Style.Triggers>
<Trigger Property="IsMouseOver" Value="True">
<Setter Property="Content">
<Setter.Value>
<Rectangle>
<Rectangle.Fill>
<DrawingBrush>
<DrawingBrush.Drawing>
<DrawingGroup>
<DrawingGroup.Children>
<!-- This Binding does not work -->
<GeometryDrawing Brush="{Binding Foreground, RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type Button}}}"
Geometry="M6,9 1,9 1,5 6,5z M7,10 0,10 0,3 7,3z M10,7 7,7 7,6 9,6 9,2 4,2 4,3 3,3 3,0 10,0z" />
</DrawingGroup.Children>
</DrawingGroup>
</DrawingBrush.Drawing>
</DrawingBrush>
</Rectangle.Fill>
</Rectangle>
</Setter.Value>
</Setter>
</Trigger>
</Style.Triggers>
</Style>
但是,它给了我这个错误
System.Windows.Data Error: 4 : Cannot find source for binding with reference 'RelativeSource FindAncestor, AncestorType='System.Windows.Controls.Button', AncestorLevel='1''.
我不知道为什么,因为 Binding 在 Style
的 Setter
中有效 ,但在 Style
中无效]的Trigger
的Setter
.
我不知道为什么它在后者中不起作用或如何解决它。
非常感谢任何帮助!
编辑:
我也尝试了 {TemplateBinding Button.Foreground}
和 {RelativeSource = {RelativeSource TemplatedParent}}
,它们都不起作用,所以现在的问题是:如何绑定到 Style
上的 属性的目标在 Trigger
?
将 Content
从 Style
更改为 Setters
和 Triggers
是不好的做法,它允许样式缓存元素和使用相同元素的各种问题您的情况下多个按钮的内容,这在 wpf 中是不允许的。
Triggers
中的 Binding
无法工作,因为它在创建时与按钮不在同一可视化树中。这就是数据错误告诉您的内容。
你真正想要的是改变按钮的ControlTemplate
。不同之处在于 ControlTemplate
中的新元素是为具有此样式的每个按钮创建的。
控件模板示例:
<ControlTemplate x:Key="ButtonBaseControlTemplate1" TargetType="{x:Type ButtonBase}">
<Border x:Name="border" BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="{TemplateBinding BorderThickness}" Background="{TemplateBinding Background}" SnapsToDevicePixels="True">
<Grid>
<Rectangle x:Name="normalIcon">
//same as before
</Rectangle>
<Rectangle x:Name="mouseOverIcon" Visibility="Collapsed">
//same as before
</Rectangle>
<ContentPresenter x:Name="contentPresenter" ContentTemplate="{TemplateBinding ContentTemplate}" Content="{TemplateBinding Content}" ContentStringFormat="{TemplateBinding ContentStringFormat}" Focusable="False" HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}" Margin="{TemplateBinding Padding}" RecognizesAccessKey="True" SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}" VerticalAlignment="{TemplateBinding VerticalContentAlignment}"/>
</Grid>
</Border>
<ControlTemplate.Triggers>
//other triggers from default template
<Trigger Property="IsMouseOver" Value="True">
<Setter Property="Background" TargetName="border" Value="#FFBEE6FD"/>
<Setter Property="BorderBrush" TargetName="border" Value="#FF3C7FB1"/>
<Setter Property="Visibility" TargetName="normalIcon" Value="Collapsed"/>
<Setter Property="Visibility" TargetName="mouseOverIcon" Value="Visible"/>
</Trigger>
//other triggers from default template
</ControlTemplate.Triggers>