从XAML中的ControlTemplate访问Button的Tag属性

时间:2013-07-26 12:40:55

标签: wpf xaml binding parent controltemplate

在我的窗口中,我有一系列的六个按钮,指示我的ViewModel的一个属性的六种可能状态。需要突出显示活跃的那个。为此,我为按钮创建了以下ControlTemplate:

<ControlTemplate x:Key="SnijRichtingTemplate" TargetType="Button">
    <Border Name="toggleButton" BorderThickness="1" BorderBrush="{StaticResource KleurRadioCheckOuter}" Background="Transparent" Width="20" Height="20" Cursor="Hand">
        <TextBlock Name="text" Foreground="{StaticResource KleurRadioCheckOuter}"
                   Text="{Binding RelativeSource={RelativeSource TemplatedParent}, Path=Tag}"
                   ToolTip="{Binding RelativeSource={RelativeSource TemplatedParent}, Path=Tag.ToolTip}"
                   HorizontalAlignment="Center" VerticalAlignment="Center" />
    </Border>

    <ControlTemplate.Triggers>
        <DataTrigger Value="True">
            <DataTrigger.Binding>
                <MultiBinding Converter="{StaticResource EqualityToBooleanConverter}">
                    <Binding Path="SnijRichting" />
                    <Binding Path="Tag" RelativeSource="{RelativeSource TemplatedParent}" />
                </MultiBinding>
            </DataTrigger.Binding>
            <Setter TargetName="toggleButton" Property="BorderBrush" Value="{StaticResource KleurTekstDonker}" />
            <Setter TargetName="text" Property="Foreground" Value="{StaticResource KleurTekstDonker}" />
        </DataTrigger>
        <Trigger Property="IsMouseOver" Value="True">
            <Setter TargetName="toggleButton" Property="BorderBrush" Value="{StaticResource Kleur2}" />
            <Setter TargetName="text" Property="Foreground" Value="{StaticResource Kleur2}" />
        </Trigger>
    </ControlTemplate.Triggers>
</ControlTemplate>

然后使用模板:

<Button Grid.Column="0" Template="{StaticResource SnijRichtingTemplate}"
        HorizontalAlignment="Right" Click="SnijRichting_Click"
        Tag="{StaticResource XLinks}" />

标签只是XAML中定义的实例:

<wg:SnijRichting x:Key="XLinks" SnijAs="X" Negatief="True" />

MultibindingConverter没什么特别的:

public class EqualityToBooleanConverter : IMultiValueConverter
{
    public object Convert(object[] values, Type targetType, object parameter, System.Globalization.CultureInfo culture)
    {
        return values[0] == values[1];
    }

    public object[] ConvertBack(object value, Type[] targetTypes, object parameter, System.Globalization.CultureInfo culture)
    {
        throw new NotImplementedException();
    }
}

基本上,每个按钮都有一个带有新值的标签。在单击处理程序中,ViewModel的属性设置为按钮的Tag。通过检查按钮的Tag是否等于ViewModel属性来更新按钮状态。

问题是这不起作用。执行EqualityToBooleanConverter时,第二个值为null。通过从第二个绑定中删除Path =“Tag”位,我看到TemplatedParent是一个ContentPresenter而不是我期望的Button,这解释了为什么Tag为null。当然,我可以编写一个ValueConverter来使用VisualTreeHelper.GetParent获取正确的值来获取ContentPresenter的父级(返回所需的Button),但是肯定必须有一种方法可以从XAML执行此操作吗?显而易见的Path =“Parent.Tag”不起作用,因为ContentPresenter的Parent显然是边框。

有没有人知道如何从XAML访问按钮的Tag属性?

1 个答案:

答案 0 :(得分:3)

发现问题。事实证明你需要{RelativeSource Mode = Self},而不是{RelativeSource TemplatedParent}。