TemplatedParent在MultiBinding中不起作用:每次都获得“UnsetValue”

时间:2016-08-25 14:55:59

标签: wpf multibinding wpf-style

我正在尝试将样式控件的可见性绑定到其标记等于TabControl的选定索引的条件。

我使用RelativeSource TemplatedParent但它没有被设置,我怀疑是因为我没有在Style中设置Template属性。

这是我的代码:

    <Grid x:Name="Telas" Grid.Column="1">
        <Grid.Resources>
            <vw:TagIsIndexBooleanConverter x:Key="TagIsIndexBooleanConverter"/>
            <Style x:Key="SelectedIndexVisibleStyle" TargetType="UserControl">
                <Setter Property="Visibility" Value="Hidden"/>
                <Style.Triggers>
                    <DataTrigger Value="True">
                        <DataTrigger.Binding>
                            <MultiBinding Converter="{StaticResource TagIsIndexBooleanConverter}">
                                <Binding Path="Tag" RelativeSource="{RelativeSource TemplatedParent}"/>
                                <Binding Path="SelectedIndex" ElementName="menu"/>
                            </MultiBinding>
                        </DataTrigger.Binding>
                        <Setter Property="Visibility" Value="Visible"/>
                    </DataTrigger>
                </Style.Triggers>
            </Style>
        </Grid.Resources>

        <vw:TelaColetaView
            x:Name="telaColeta"
            DataContext="{Binding TelaColetaVM}"
            Style="{StaticResource SelectedIndexVisibleStyle}"
            Tag="0"/>

        <vw:TelaPacientesView
            x:Name="telaPacientes"
            DataContext="{Binding TelaPacientesVM}"
            Style="{StaticResource SelectedIndexVisibleStyle}"
            Tag="1"/>

        <vw:TelaConfiguraçõesView
            x:Name="telaConfigurações"
            DataContext="{Binding TelaConfiguraçõesVM}"
            Style="{StaticResource SelectedIndexVisibleStyle}"
            Tag="4"/>

    </Grid>

转换器:

public class TagIsIndexBooleanConverter : IMultiValueConverter
{
    public object Convert(object[] values, Type targetType, object parameter, CultureInfo culture)
    {
        if (values.Any(v => v == null || v == DependencyProperty.UnsetValue))
            return Binding.DoNothing;

        var tag = System.Convert.ToInt32(values[0]);
        var index = System.Convert.ToInt32(values[1]);
        var result = tag == index;
        return result;
    }

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

1 个答案:

答案 0 :(得分:2)

在这种情况下你不能使用TemplatedParent,因为它不是一个;这意味着要在ControlTemplate中使用,以指定绑定的来源是您将模板应用到的控件。

<Binding Path="Tag" RelativeSource="{RelativeSource TemplatedParent}"/>

但这不在ControlTemplate内。相反,Tag只是您设计风格的属性。通常,您会为Tag执行此类触发器:

<Trigger Property="Tag" Value="0">

...但是您需要多重绑定才能从SelectedIndex获取menu,并且它必须是MultiDataBinding,因为您需要指定ElementName }。

所以你需要一个绑定。要绑定到您自己的某个属性而不是DataContext的属性,请绑定RelativeSource Self

<Binding Path="Tag" RelativeSource="{RelativeSource Self}" />

OP还发现他必须将TargetType的{​​{1}}设置为Style,以使"UserControl"绑定生效。