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

TemplatedParent not working in MultiBinding: getting "UnsetValue" everytime

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

我用了RelativeSource TemplatedParent,但是没有设置,我怀疑是因为我没有在样式中设置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();
    }
}

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

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

但这不在 ControlTemplate 内。相反,Tag 只是您正在设置样式的对象的 属性。通常你会为 Tag:

做这样的触发器
<Trigger Property="Tag" Value="0">

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

所以你需要绑定。要绑定到您自己的属性之一而不是 DataContext 的 属性,您可以使用 SelfRelativeSource 进行绑定:

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

OP 还发现他必须将 StyleTargetType 设置为 "UserControl",才能使 Tag 绑定生效。