将TreeView绑定到包含许多对象的单个对象

时间:2017-02-23 18:06:00

标签: c# wpf treeview

我有这样的约束:

<TreeView x:Name="QueuesTreeView" 
          ItemsSource="{Binding ElementName=MainWindowName, Path=QueueHierarchy, Mode=OneWay}" 
          BorderThickness="0"> ...

QueueHierarchy是:

public class QueueHierarchy
{
    public QueueHierarchy()
    {
        Children = new List<QueueHierarchy>();
    }
    public int QueueID { get; set; }
    public IList<QueueHierarchy> Children { get; set; }
}

我想知道如何让TreeView绑定到此?使用HierarchicalDataTemplateDataTemplate的问题是绑定数据类型相同......它是QueueHierarchy
那我怎么能区分它们呢?

1 个答案:

答案 0 :(得分:2)

如果您正试图弄清楚如何为子QueueHierarchy项提供与其父级不同的模板,HierarchicalDataTemplate.ItemTemplate应该完成这项工作:

<TreeView
    ItemsSource="{Binding ElementName=MainWindowName, Path=QueueHierarchy.Children}"
    >
    <TreeView.ItemTemplate>
        <HierarchicalDataTemplate ItemsSource="{Binding Children}">
            <HierarchicalDataTemplate.ItemTemplate>
                <DataTemplate>
                    <!-- Blue bkg only to show that it's a different template -->
                    <TextBlock Background="SkyBlue" Text="{Binding QueueID}" />
                </DataTemplate>
            </HierarchicalDataTemplate.ItemTemplate>

            <TextBlock Text="{Binding QueueID}" />
        </HierarchicalDataTemplate>
    </TreeView.ItemTemplate>
</TreeView>

如果层次结构是任意深度的,那么您也可以使子模板分层。如果HierarchicalDataTemplate没有设置ItemTemplate,则会将其用于其子女,儿童和其他人。孩子等无限期。

<HierarchicalDataTemplate ItemsSource="{Binding Children}">
    <TextBlock Text="{Binding QueueID}" />
</HierarchicalDataTemplate>

您还可以为子模板提供自己的子模板。

如果您希望根集合项目成为树中的项目,我可以考虑几个选项。

您可以编写一个廉价且开朗的值转换器,它接收任何给定的对象并返回仅包含该对象的集合。

public class EnumerateConverter : IValueConverter
{
    public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
    {
        return new List<object> { value };
    }

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

XAML:

<TreeView
    ItemsSource="{Binding ElementName=MainWindowName, Path=QueueHierarchy, Converter={StaticResource EnumerateConverter}}"
    >

或者这可行:

private QueueHierarchy _qh;
public QueueHierarchy QueueHierarchy {
    get { return _qh; }
    set {
        if (_qh != value) {
            _qh = value;
            OnPropertyChanged(nameof(QueueHierarchy));
            OnPropertyChanged(nameof(QueueHierarchyRootLevel));
    }
}
public IEnumerable<QueueHierarchy> QueueHierarchyRootLevel {
    get { yield return QueueHierarchy; }
}

或者给QueueHierarchy一个返回相同枚举的属性:

    public IEnumerable<QueueHierarchy> CollectionOfSelf {
        get { yield return this; }
    }

XAML:

<TreeView
    ItemsSource="{Binding ElementName=MainWindowName, Path=QueueHierarchy.CollectionOfSelf}"
    >

我开始认为价值转换器的想法是最正确的MVVM&#34;做法。您不希望您的视图模型担心此问题。这真的是一个观点,转换器将解决方法限制在视图范围内。