我想在我的基本TextBox样式中添加一个DataTrigger,以便它如果位于所选的DataGridCell内,则将前景颜色设置为不同的值。这是我的触发器的样子:
<Style.Triggers>
<DataTrigger Binding="{Binding RelativeSource={RelativeSource AncestorType={x:Type DataGridCell}}, Path=IsSelected}"
Value="True">
<Setter Property="Foreground"
Value="White" />
</DataTrigger>
</Style.Triggers>
这很好用,除了当我的TextBox不在DataGrid中时,Binding失败并将异常写入输出窗口。我怎么能阻止这个。
我基本上想说,如果Parent是DataGridCell,则应用此触发器,否则忽略它。
答案 0 :(得分:5)
一般情况下,只应用适用的样式。如果您希望隐式应用程序使用嵌套样式:
<Style TargetType="{x:Type DataGrid}">
<Style.Resources>
<Style TargetType="{x:Type TextBox}">
<Style.Triggers>
<DataTrigger
Binding="{Binding RelativeSource={RelativeSource AncestorType={x:Type DataGridCell}}, Path=IsSelected}"
Value="True">
<Setter Property="Foreground" Value="White" />
</DataTrigger>
</Style.Triggers>
</Style>
</Style.Resources>
</Style>
如果您要将其他部分应用于所有TextBox,请以serarate样式取出这些部分,并使用适用于DataGrid内TextBox的样式中的BasedOn
。
编辑:如果不满足条件,MultiDataTrigger似乎会立即返回,因此您可以避免绑定错误:
<Style TargetType="{x:Type TextBox}">
<Style.Resources>
<vc:HasAncestorOfTypeConverter x:Key="HasAncestorOfTypeConverter" AncestorType="{x:Type DataGridCell}" />
</Style.Resources>
<Style.Triggers>
<MultiDataTrigger>
<MultiDataTrigger.Conditions>
<Condition
Binding="{Binding RelativeSource={RelativeSource Self}, Converter={StaticResource HasAncestorOfTypeConverter}}"
Value="True" />
<Condition
Binding="{Binding RelativeSource={RelativeSource AncestorType={x:Type DataGridCell}}, Path=IsSelected}"
Value="True" />
</MultiDataTrigger.Conditions>
<Setter Property="Foreground" Value="Red" />
</MultiDataTrigger>
</Style.Triggers>
</Style>
public class HasAncestorOfTypeConverter : IValueConverter
{
public Type AncestorType { get; set; }
public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
{
if (value == null) return false;
DependencyObject current = value as DependencyObject;
while (true)
{
current = VisualTreeHelper.GetParent(current);
if (current == null)
{
return false;
}
if (current.GetType() == AncestorType)
{
return true;
}
}
}
public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
{
throw new NotSupportedException();
}
}
这当然会导致相当大的开销,所以它可能不是一个很好的解决方案,然后再次如果RelativeSource绑定失败,它也必须首先上升。