如何子类化WPF的TreeViewItem并在TreeView中使用它

5

我已经创建了一个简单的依赖属性,想要将其附加到TreeViewItem上。我已经为其他控件(如按钮)完成了类似的操作,但是无法在TreeView中使用TreeViewItem而不丢失自定义样式。使用下面的代码,我会得到“旨在应用于类型'ErrorTreeViewItem'的样式不能应用于类型'TreeViewItem'”。

public class ErrorTreeViewItem : TreeViewItem
{
    static ErrorTreeViewItem()
    {
    }

    public bool ErrorState
    {
        get { return (bool)GetValue(ErrorStateProperty); }
        set { base.SetValue(ErrorStateProperty, value); }
    }

    public static readonly DependencyProperty ErrorStateProperty =
        DependencyProperty.Register("ErrorState", typeof(bool), typeof(ErrorTreeViewItem), new UIPropertyMetadata(false));
}

我的树视图的样式看起来像这样:
      <Style TargetType="me:ErrorTreeViewItem">

        <Style.Resources>
           ...
        </Style.Resources>
            <Setter Property="HorizontalContentAlignment" Value="Stretch"/>
            <Setter Property="Template">
            <Setter.Value>
                <ControlTemplate TargetType="TreeViewItem">
                ...
            </Setter.Value>
        </Setter>

我是这样使用它的:

    <TreeView Name="ApplicationTree" ItemsSource="{Binding Applications}" HorizontalContentAlignment="Stretch" Background="#E8E8E8" >
        <TreeView.ItemContainerStyle>
            <Style TargetType="me:ErrorTreeViewItem" BasedOn="{StaticResource {x:Type TreeViewItem}}">
                <Setter Property="IsExpanded" Value="{Binding IsExpanded, Mode=TwoWay}" />
                <Setter Property="IsSelected" Value="{Binding IsSelected, Mode=TwoWay}" />
                <Setter Property="HorizontalContentAlignment" Value="Stretch"/>
            </Style>
        </TreeView.ItemContainerStyle>

你是因为不理解内置的验证服务(它们很难正确使用!)还是因为你不知道它们的存在而没有使用它们?IDataErrorInfo。 - user1228
不是这样的,我只是想根据我的依赖属性的值更改TreeView项的颜色。没想到会这么难! - user1145533
1
有几种方法可以做到这一点。如果您正在使用MVVM,Models上的IDataErrorInfo将自动触发验证并在标准WPF控件上显示无效模板。您还可以尝试在TreeViewItem上使用附加的DependencyProperty,这样您甚至不需要扩展基类等。我从未在WPF中以这种方式完成过,但我知道在Winforms中要实现这一点,您也必须扩展TreeView类,因此当您创建新的TVI时,您会返回您的类型的实例。这就是您的错误出现的地方。 - user1228
2个回答

2
您可以在您的TreeView上覆盖GetContainerForItemOverride(是的,您也需要对TreeView进行子类化)。
protected override DependencyObject GetContainerForItemOverride()
{
    return new YourCustomTreeViewItem();
}

请注意,如果您希望自定义的 TreeViewItem 生成该类型的子项,则还需要在其上覆盖 GetContainerForItem。

1

TreeView将创建默认的TreeViewItems,因此您首先需要让它创建您自己的树视图项。为此,您需要子类化TreeView并覆盖PrepareContainerForItem以返回ErrorTreeViewItem的新实例。


PrepareContainerForItem不存在,并且PrepareContainerForItemOverride不返回任何内容。 - undefined

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接