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
的 属性,您可以使用 Self
的 RelativeSource
进行绑定:
<Binding Path="Tag" RelativeSource="{RelativeSource Self}" />
OP 还发现他必须将 Style
的 TargetType
设置为 "UserControl"
,才能使 Tag
绑定生效。
我正在尝试将样式化控件的可见性绑定到其标签等于 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
的 属性,您可以使用 Self
的 RelativeSource
进行绑定:
<Binding Path="Tag" RelativeSource="{RelativeSource Self}" />
OP 还发现他必须将 Style
的 TargetType
设置为 "UserControl"
,才能使 Tag
绑定生效。