具有混合类型的TreeView HierarchicalDataTemplate

时间:2019-07-09 11:46:20

标签: c# wpf treeview hierarchicaldatatemplate

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

从昨天开始我遇到了一个小问题,我读了很多树视图绑定的例子,但是我没有成功使用多重类型绑定...

它必须看起来像这样:

我的机器(0级)

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

--------Keyboard1⬇️(2级)

--------Keyboard2⬇️(2级)

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

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

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

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

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

---------VideoCard1⬇️(2级)

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

我的所有组件设备都有一个Viewmodel:

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”

每个类似示例的链接都将对我有所帮助。 预先感谢

3 个答案:

答案 0 :(得分:1)

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

您应该做的是将DeviceInfo类转换为具有单个子属性的数据绑定友好型视图模型类:

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

然后,您将ItemsSource属性绑定到四个IEnumerable<Item>根对象的Item,即1级键盘,操作系统,CPU和视频卡节点。

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

<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 }并添加“静态”根级别在您的XAML标记中显式地添加到TreeView

<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>

答案 1 :(得分:1)

要实现所需的功能,只需将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>

答案 2 :(得分:0)

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

因此,它仅显示模型的默认ToString()。这就是为什么您只看到文本“ Model.DeviceInfo”的原因。

以下链接将对您有所帮助。

Data Templating Overview