具有混合类型的 TreeView HierarchicalDataTemplate

TreeView HierarchicalDataTemplate with mixed types

我实际上正在开发我的第一个 WPF 应用程序,它必须在具有分层数据的树视图中显示我的计算机的所有组件。

从昨天开始,我遇到了一个小问题,我阅读了大量的 treeview 绑定示例,但我没有成功绑定多个类型...

它必须看起来像这样:

我的机器(0级)

-----键盘⬇️(1级)

--------键盘1⬇️(2级)

--------键盘2⬇️(2级)

-----OS⬇️(1级)

-----CPU⬇️(1级)

--------CPU1⬇️(2级)

--------CPU2⬇️(2级)

-----VideoCard⬇️(1级)

------------VideoCard1⬇️(level 2)

------------VideoCard2⬇️(2级)

我有一个包含所有组件设备的视图模型:

DeviceInfo.cs :

public class DeviceInfo
{
    public string ComputerName { get; set; }

    public Bios Bios { get; set; }
    public ComputerSystem ComputerSystem { get; set; }
    public List<Keyboard> Keyboards { get; set; }
    public OperatingSystem OperatingSystem { get; set; }
    public List<Processor> Processors { get; set; }
    public List<VideoCard> VideoCards { get; set; }
}

每个组件包含特定的属性,例如Keyboard.cs:

public class Keyboard
{
    public string Description { get; set; }
    public string DeviceID { get; set; }
}

我为我的树视图尝试了类似的方法,我在 Mainwindow 中像这样绑定数据:

DeviceTree.ItemsSource = deviceInfos;

MainWindow.xaml :

 <TreeView Margin="10" BorderThickness="2" BorderBrush="Black" Name="DeviceTree">
                <TreeView.Resources>
                    <HierarchicalDataTemplate DataType="x:Type data:DeviceInfo" ItemsSource="{Binding Keyboards}">
                        <TextBlock Text="{Binding Description}"></TextBlock>
                    </HierarchicalDataTemplate>
                    <HierarchicalDataTemplate DataType="x:Type data:DeviceInfo" ItemsSource="{Binding OS}">
                        <TextBlock Text="{Binding Version}"></TextBlock>
                    </HierarchicalDataTemplate>
                    <HierarchicalDataTemplate DataType="x:Type data:DeviceInfo" ItemsSource="{Binding VideoCard}">
                        <TextBlock Text="{Binding SerialNumber}"></TextBlock>
                    </HierarchicalDataTemplate>
                </TreeView.Resources>
   </TreeView>

实际上它在我的树视图模板中看起来像这样:

"Model.DeviceInfo"

每个link类似的例子都会对我有所帮助。 提前致谢

当 WPF 不知道如何在视图上显示您的模型时,通常会发生这种情况。 在您的源代码中,您已经定义了在 TextBox 中显示模型的每个属性的模板。但是您还没有将它们应用到您的视图中。

所以它只显示模型的默认 ToString()。这就是为什么您只看到文本 "Model.DeviceInfo".

以下link会对您有所帮助。

Data Templating Overview

一个HierarchicalDataTemplate只支持一个child属性。为同一类型定义三个模板是没有意义的。无论如何,只有它们可以在运行时应用。

你应该做的是将你的 DeviceInfo class 转换成一个 data-binding 友好的视图模型 class,它有一个 child 属性:

public class Item
{
    public string Header { get; set; }
    public IEnumerable<Item> Children { get; set; }
}

然后您将 ItemsSource 属性 绑定到四个 Item 根 objects 的 IEnumerable<Item>,即 1 级键盘,OS、CPU 和 VideoCard 节点。

还要注意将 DataType 属性 设置为 XAML 中的实际类型的语法:

<TreeView Margin="10" BorderThickness="2" BorderBrush="Black" Name="DeviceTree">
    <TreeView.Resources>
        <HierarchicalDataTemplate DataType="{x:Type local:Item}" ItemsSource="{Binding Children}">
            <TextBlock Text="{Binding Header}" />
        </HierarchicalDataTemplate>
    </TreeView.Resources>
</TreeView>

编辑:

如果级别总数不是动态的,即您总是有两个级别,您可以设置或绑定 ItemsSource 属性 到 new List<DeviceInfo>(1) { deviceInfos } 并添加"static" 根级别到 TreeView 在您的 XAML 标记中明确:

<TreeView Margin="10" BorderThickness="2" BorderBrush="Black" Name="DeviceTree">
    <TreeViewItem Header="Keyboards" ItemsSource="{Binding Keyboards}">
        <TreeViewItem.ItemTemplate>
            <DataTemplate>
                <TextBlock Text="{Binding Description}" />
            </DataTemplate>
        </TreeViewItem.ItemTemplate>
    </TreeViewItem>
    <TreeViewItem Header="Operating Systems" ItemsSource="{Binding OperatingSystem}">
        <TreeViewItem.ItemTemplate>
            <DataTemplate>
                <TextBlock Text="{Binding Version}" />
            </DataTemplate>
        </TreeViewItem.ItemTemplate>
    </TreeViewItem>
    <!-- + TreeViewItems for Processors and VideoCards -->
</TreeView>

要制作你想要的东西,你只需将 TreeViewItem 放在你的主 TreeView 中。如果你想更上一层楼,你只需要添加一个带有 TreeViewItem 的 ItemTemplate。我给你一个简单对象(Bios)的例子,然后是一个对象列表(键盘)。 TreeView 的 ItemSources 是 DeviceInfo 的列表。

xaml :

<TreeView x:Name="MyTreeView">
    <TreeView.ItemTemplate>
        <DataTemplate>
            <StackPanel Orientation="Vertical">
                <TreeViewItem Header="{Binding ComputerName}">
                    <TreeViewItem.Items>
                        <TreeViewItem Header="Bios">
                            <StackPanel Orientation="Vertical">
                                <TextBlock Text="{Binding Bios.Description}"/>
                                <TextBlock Text="{Binding Bios.Name}"/>
                                <TextBlock Text="{Binding Bios.Version}"/>
                            </StackPanel>
                        </TreeViewItem>
                        <TreeViewItem Header="Keyboard" ItemsSource="{Binding Keyboards}">
                            <TreeViewItem.ItemTemplate>
                                <DataTemplate>
                                    <TreeViewItem Header="{Binding DeviceID}">
                                        <TextBlock Text="{Binding Description}"/>
                                    </TreeViewItem>
                                </DataTemplate>
                            </TreeViewItem.ItemTemplate>
                        </TreeViewItem>
                    </TreeViewItem.Items>
                </TreeViewItem>
            </StackPanel>
        </DataTemplate>
    </TreeView.ItemTemplate>
</TreeView>