wpf - 基于祖先类型的存在设置样式

标签 wpf xaml findancestor

我有 2 套 TextBlocks其中一些在 ItemControl其中一些不是。
我想制作一种样式(仅基于类型)来设置 TextBlock 的背景如果它的祖先是 ItemControl .
我可以使用下面的代码来做到这一点,但我的问题是在日志(和输出窗口)上显示了一条数据投标错误消息,因为 TextBlocks哪些没有 ItemControl作为他们的祖先。
有没有更好的方法来完成此任务并避免出现此错误消息?

<Grid>
    <Grid.Resources>
        <local:HasAncestorConverter x:Key="HasAncestorConverter" />
        <Style TargetType="TextBlock">            
            <Style.Triggers>
                <DataTrigger
                    Binding="{Binding RelativeSource={RelativeSource
                    AncestorType={x:Type ItemsControl}},
                    Converter={StaticResource HasAncestorConverter}}" Value="True">
                    <Setter Property="Background"
                            Value="{Binding Tag,
                            RelativeSource={RelativeSource
                            AncestorType={x:Type ItemsControl}}}" />
                </DataTrigger>
            </Style.Triggers>
        </Style>
    </Grid.Resources>
    <StackPanel>
        <TextBlock Text="Out of ItemControl" />
        <ItemsControl Tag="Blue" >
            <TextBlock Text="Inside of ItemControl" />
        </ItemsControl>
    </StackPanel>
</Grid>    
转换器:
class HasAncestorConverter : IValueConverter
{
    public object Convert(object value, Type targetType, object parameter,
        System.Globalization.CultureInfo culture)
    {
        return value != null;
    }
    public object ConvertBack(object value, Type targetType, object parameter,
        System.Globalization.CultureInfo culture)
    {
        throw new NotImplementedException();
    }
}
错误信息:

System.Windows.Data Error: 4 : Cannot find source for binding with reference 'RelativeSource FindAncestor, AncestorType='System.Windows.Controls.ItemsControl', AncestorLevel='1''. BindingExpression:Path=; DataItem=null; target element is 'TextBlock' (Name=''); target property is 'NoTarget' (type 'Object')

最佳答案

我认为@Xameli 解决方案正是您真正要寻找的...
但如果你只是必须以一种风格来做,那么你可以使用 VisualTreeHelper 来实现它像那样:

<Style.Triggers>
            <DataTrigger Binding="{Binding RelativeSource={RelativeSource AncestorType={x:Type ItemsControl}}, Converter={StaticResource HasAncestorConverter}}" Value="True">
                <Setter Property="Background"
                        Value="{Binding Tag,RelativeSource={RelativeSource Self}}" />

            </DataTrigger>
        </Style.Triggers>

转换器:
class HasAncestorConverter : IValueConverter
{
    public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
    {
        //you probably will have to look a few levels up
        var parent = VisualTreeHelper.GetParent(value) as ItemsControl;
        return item != null; 
    }

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

关于wpf - 基于祖先类型的存在设置样式,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19645660/

相关文章:

wpf - Silverlight 和 Wpf 中错误格式验证错误消息的自定义

c# - DataGrid 的意外行为

c# - WPF 绑定(bind)问题 - UI 更新,对象不更新

c# - 使用c#在wpf中的弹出定位

wpf - 如何获得 WPF 验证错误

c# - 无法将可检查的 MenuItem 绑定(bind)到父窗口的 Topmost (始终位于顶部)属性

c# - 列表框(多选)选定索引

c# - WPF 类库中的 ResourceDictionary

c# - WPF 由祖传属性触发