WPF TreeView 如何指定多个相同类型的属性作为子节点的来源

WPF TreeView How to specify Multiple Properties of same type as sources of Child nodes

我有一个规则列表 class 需要绑定到 Treeview 但 Treeview 节点的层次结构应该是这样的

如果
--IF2
--ElseIF
----IF3
--否则
----IF4

这是规则class

public class Rule
{
    private List<RuleTag> elseIf = new List<RuleTag>();

    public RuleTag IF { get; set; }
    public RuleTag Else { get; set; }

    public List<RuleTag> ElseIf
    {
        get { return elseIf; }
    }

    public Rule() { }
}

RuleTag 定义如下

public class RuleTag
{
    private List<Rule> children = new List<Rule>();

    public List<Rule> Children
    {
        get { return children; }
        set { children = value; }
    }

    public RuleTag() { }
}

上例中IF2是成员IF.Children,ElseIF是Rule.ElseIF[0](如果数组中有多个ElseIf都需要显示),IF3是成员Rule.ElseIf[0].Children 和 IF4 是 Rule.Else.Children

的成员

我已经尝试过 HierarchicalDataTemplate,但我只能绑定到 IF 的子元素,无法将 Else 和 ElseIF 显示为子元素

这是我的 XAML

<TreeView.Resources>
    <HierarchicalDataTemplate DataType="{x:Type TangoRules:Rule}" ItemsSource="{Binding IF.Children}">
        <TextBlock Text="IF" />
    </HierarchicalDataTemplate>
</TreeView.Resources>

尝试使用两个级别的分层数据模板:

<HierarchicalDataTemplate ItemsSource="{Binding RuleCollection}">
            <TextBlock Text="{Binding IF}" />                       
            <HierarchicalDataTemplate.ItemTemplate>
                <HierarchicalDataTemplate ItemsSource="{Binding Children}">
                    <HierarchicalDataTemplate.ItemTemplate>
                        <DataTemplate>
                            <TextBlock Text="{Binding}" />
                        </DataTemplate>
                    </HierarchicalDataTemplate.ItemTemplate>                   
                </HierarchicalDataTemplate>
            </HierarchicalDataTemplate.ItemTemplate>

        </HierarchicalDataTemplate>

我通过修改规则 class 使用 CompositeCollection 解决了它

public class Rule : INotifyPropertyChanged
{
    private ObservableCollection<RuleTag> elseIf = new ObservableCollection<RuleTag>();
    private RuleTag _else;
    private CompositeCollection children = new CompositeCollection();

    public RuleTag IF { get; set; }
    public RuleTag Else
    {
        get { return _else; }
        set
        {
            _else = value;
            OnPropertyChanged("Children");
        }
    }

    public ObservableCollection<RuleTag> ElseIf
    {
        get { return elseIf; }
    }

    public CompositeCollection Children
    {
        get
        {
            children.Clear();
            children.Add(new CollectionContainer() { Collection = IF.Children });
            children.Add(new CollectionContainer() { Collection = ElseIf });
            if (Else != null)
                children.Add(Else);
            return children;
        }
    }

    public event PropertyChangedEventHandler PropertyChanged;

    protected void OnPropertyChanged(string name)
    {
        PropertyChangedEventHandler handler = PropertyChanged;
        if (handler != null)
        {
            handler(this, new PropertyChangedEventArgs(name));
        }
    }
}

请注意,我现在还实现了 INotifyPropertyChanged 接口,这是因为 class 中的其他部分不是集合。现在,当 Rule class 被实例化时,如果 Else 为空,它不会被添加到 CompositeCollection,但如果稍后设置,我会通知 CompositeCollection 的所有观察者这个 属性 已更改。此外,我已经列出了所有清单,例如IF.Childre,列出 observablecollection