如何在具有相同名称的情况下区分TemplateBindings

时间:2014-06-25 20:31:15

标签: wpf xaml

我已切换按钮,并希望为它们创建样式树。目标是拥有一个主要样式和控件模板(使用TemplateBinding) - 然后每个不同的外观按钮将拥有它自己的样式,我可以简单地更改一些Setter属性来调整我需要的任何东西。这使我不得不为每个按钮制作一个可能庞大的控制模板。当我想改变它们的外观时,这也节省了时间。使用切换按钮,我希望在其中有两个路径,并且IsChecked的触发器可以更改不透明度(Path1将是默认值,Path2将在检查时显示为可见的)。但是我不能区分两个Path.Data,因为迷你样式不接受TargetName,而触发器不接受TemplateBindings。

示例:

<Style x:Key="DefaultToggleButton" TargetType="{x:Type ToggleButton}">
    <Setter Property="HorizontalContentAlignment" Value="Center"/>
    <Setter Property="VerticalContentAlignment" Value="Center"/>
    <Setter Property="Padding" Value="0,0,1,1"/>
    <Setter Property="Background" Value="Transparent"/>
    <Setter Property="Border.Padding" Value="1"/>
    <Setter Property="Path.Fill" Value="{DynamicResource FillBrush}"/>
    <Setter Property="Path.StrokeThickness" Value="0"/>

    <Setter Property="Template">
        <Setter.Value>
            <ControlTemplate TargetType="{x:Type ToggleButton}">
                <Viewbox 
                    x:Name="viewbox" 
                    HorizontalAlignment="Center" 
                    VerticalAlignment="Center" 
                    Width="Auto" 
                    Height="Auto">
                    <Border 
                        SnapsToDevicePixels="true"
                        Width="16" 
                        Height="16" 
                        BorderThickness="0" 
                        Background="{TemplateBinding Background}"
                        x:Name="border" 
                        HorizontalAlignment="Center" 
                        VerticalAlignment="Center"  
                        Padding="{TemplateBinding Border.Padding}">
                        <Grid 
                            HorizontalAlignment="Center" 
                            VerticalAlignment="Center"  
                            Width="Auto" 
                            Height="Auto">
                            <Path 
                                Opacity="1"
                                Margin="2" 
                                Name="ButtonPath1" 
                                Fill="{TemplateBinding Path.Fill}" 
                                Stretch="Fill" 
                                StrokeEndLineCap="Round" 
                                StrokeStartLineCap="Round" 
                                StrokeThickness="{TemplateBinding Path.StrokeThickness}" 
                                Data="{TemplateBinding Path.Data}"   <!-- This one -->
                                HorizontalAlignment="Center" 
                                VerticalAlignment="Center"/>
                           <Path 
                                Opacity="0"
                                Margin="2" 
                                Name="ButtonPath2" 
                                Fill="{TemplateBinding Path.Fill}" 
                                Stretch="Fill" 
                                StrokeEndLineCap="Round" 
                                StrokeStartLineCap="Round" 
                                StrokeThickness="{TemplateBinding Path.StrokeThickness}" 
                                Data="{TemplateBinding Path.Data}"   <!-- And this one -->
                                HorizontalAlignment="Center" 
                                VerticalAlignment="Center"/>
                        </Grid>
                    </Border>
                </Viewbox>
                <ControlTemplate.Triggers>
                    <Trigger Property="IsChecked" Value="True">
                        <Setter TargetName="ButtonPath1" Property="Opacity" Value="0"/>
                        <Setter TargetName="ButtonPath2" Property="Opacity" Value="1"/>
                    </Trigger>
                    <Trigger Property="IsChecked" Value="False">
                        <Setter TargetName="ButtonPath1" Property="Opacity" Value="1"/>
                        <Setter TargetName="ButtonPath2" Property="Opacity" Value="0"/>
                    </Trigger>
                </ControlTemplate.Triggers>
            </ControlTemplate>
        </Setter.Value>
    </Setter>
</Style>

<Style 
    x:Key="ActualButton" 
    TargetType="{x:Type ToggleButton}" 
    BasedOn="{StaticResource DefaultToggleButton}">

<!-- How can I point the properties below to the correct Path.Data? 
     Setting TargetName did not work since it is in a different Style. -->

    <Setter Property="Path.Data" Value="M 0 0 L 6 0 L 3 6 Z"/>     <!-- ButtonPath -->
    <Setter Property="Path.Data" Value="M 0 6 L 3 0 L 6 6 Z"/>     <!-- ButtonPath2 -->
</Style>

2 个答案:

答案 0 :(得分:1)

由于TemplateBinding从您应用模板的实际控件中获取值,因此它可以为不同的控件提供单个值而不是不同的值。当您在Path.Data的两个不同位置使用TemplateBinding时,它会在两个位置为您提供相同的值。如果你想要不同的值,那么用两个不同的属性绑定它。

我认为您可以通过为DependencyProperty创建路径类型的自定义ToggleButton来实现此目的。一个用于未选中,另一个用于检查。

答案 1 :(得分:0)

这可能是一个好主意,也可能不是一个好主意,但我设法通过在Style.Triggers下将“IsChecked”触发器移动到ActualButton(而不是Default)样式来完成这项工作。

示例:

<Style x:Key="DefaultToggleButton" TargetType="{x:Type ToggleButton}">
    <Setter Property="HorizontalContentAlignment" Value="Center"/>
    <Setter Property="VerticalContentAlignment" Value="Center"/>
    <Setter Property="Padding" Value="0,0,1,1"/>
    <Setter Property="Background" Value="Transparent"/>
    <Setter Property="Border.Padding" Value="1"/>
    <Setter Property="Path.Fill" Value="{DynamicResource FillBrush}"/>
    <Setter Property="Path.StrokeThickness" Value="0"/>

    <Setter Property="Template">
        <Setter.Value>
            <ControlTemplate TargetType="{x:Type ToggleButton}">
                <Viewbox 
                    x:Name="viewbox" 
                    HorizontalAlignment="Center" 
                    VerticalAlignment="Center" 
                    Width="Auto" 
                    Height="Auto">
                    <Border 
                        SnapsToDevicePixels="true"
                        Width="16" 
                        Height="16" 
                        BorderThickness="0" 
                        Background="{TemplateBinding Background}"
                        x:Name="border" 
                        HorizontalAlignment="Center" 
                        VerticalAlignment="Center"  
                        Padding="{TemplateBinding Border.Padding}">
                        <Grid 
                            HorizontalAlignment="Center" 
                            VerticalAlignment="Center"  
                            Width="Auto" 
                            Height="Auto">
                            <Path 
                                Opacity="1"
                                Margin="2" 
                                Name="ButtonPath1" 
                                Fill="{TemplateBinding Path.Fill}" 
                                Stretch="Fill" 
                                StrokeEndLineCap="Round" 
                                StrokeStartLineCap="Round" 
                                StrokeThickness="{TemplateBinding Path.StrokeThickness}" 
                                Data="{TemplateBinding Path.Data}"
                                HorizontalAlignment="Center" 
                                VerticalAlignment="Center"/>
                        </Grid>
                    </Border>
                </Viewbox>
            </ControlTemplate>
        </Setter.Value>
    </Setter>
</Style>

<Style 
    x:Key="ActualButton" 
    TargetType="{x:Type ToggleButton}" 
    BasedOn="{StaticResource DefaultToggleButton}">
    <Setter Property="Path.Data" Value="M 0 0 L 6 0 L 3 6 Z"/> 
    <Style.Triggers>
        <Trigger Property="IsChecked" Value="True">
            <Setter Property="Path.Data" Value="M 0 6 L 3 0 L 6 6 Z"/>
        </Trigger>
    </Style.Triggers>       
</Style>