WPF绑定到触发器

时间:2017-11-01 18:53:10

标签: wpf binding triggers styles relativesource

我想在GeometryDrawing内置Button,当鼠标悬停在Geometry上时,Button会更改<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>

Style

然而,它给了我这个错误

  

System.Windows.Data错误:4:无法找到绑定源,引用'RelativeSource FindAncestor,AncestorType ='System.Windows.Controls.Button',AncestorLevel ='1''。

我不知道为什么,因为 Binding在Setter的{​​{1}}中有效,而在Style的{​​{1}} Trigger 1}} Setter

我不知道为什么它不适用于后者或如何解决它。

非常感谢任何帮助!

编辑: 我还尝试了{TemplateBinding Button.Foreground}{RelativeSource = {RelativeSource TemplatedParent}}这两个都没有用,所以现在的问题是:如何绑定到Style目标中的属性{ {1}}?

1 个答案:

答案 0 :(得分:3)

Content StyleSetters更改Triggers是不好的做法,它允许样式缓存元素出现各种问题,并使用与内容相同的元素对于你的情况下的多个按钮,这在wpf中是不允许的。

Binding中的Triggers无法正常工作,因为它与创建时的按钮不在同一个视觉树中。这就是数据错误告诉你的。

您真正想要的是更改按钮的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>