将自定义类作为TreeViewItem添加到TreeView WPF [英] Adding Custom Class as TreeViewItem to TreeView WPF

查看:77
本文介绍了将自定义类作为TreeViewItem添加到TreeView WPF的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我的TreeView如下图所示:

I have scenario where my TreeView look like below:

  • MainParent
  • .>-父母
  • ...>-Child1
  • ...>-Child2
  • ...>-Child3
  • ...>-Child4
  • ...>-Child5
  • ......> Child1_Of_Child5
  • ...........> Child1(Child1_Of_Child5)
  • ...........> Child2(Child1_Of_Child5)
  • ......> Child2_of_Child5
  • ...........> Child1(Child2_Of_Child5)
  • ...........> Child2(Child2_Of_Child5)
  • MainParent
  • .>-Parent
  • ...>--Child1
  • ...>--Child2
  • ...>--Child3
  • ...>--Child4
  • ...>--Child5
  • ......> Child1_Of_Child5
  • ...........>Child1(Child1_Of_Child5)
  • ...........>Child2(Child1_Of_Child5)
  • ......> Child2_of_Child5
  • ...........>Child1(Child2_Of_Child5)
  • ...........>Child2(Child2_Of_Child5)

我能够使用HierarchicalDataTemplate将ObservableCollection绑定到Child1/Child2/../Child5. 虽然我可以将Child1_Of_Child5添加到Child5 ObservableCollection(在调试模式下看到),但UI/Treeview中没有反映同样的内容.

I am able to bind ObservableCollection till Child1/Child2/../Child5 using HierarchicalDataTemplate. Though I am able to add Child1_Of_Child5 to Child5 ObservableCollection (seen in debug mode), Same is not reflecting in UI/Treeview.

以下是我的XAML代码:

Below is my XAML code:

<TreeView.ItemTemplate>
                    <HierarchicalDataTemplate DataType="{x:Type VM:ProjectViewModel}" ItemsSource="{Binding SelectActivityViewModelCollection}">
                        <StackPanel Orientation="Horizontal">
                            <Image Source="./resources/New_Package.png" Width="15" Height="15"/>
                            <TextBlock Text="{Binding Header}"></TextBlock>
                        </StackPanel>
                        <HierarchicalDataTemplate.ItemTemplate>
                            <HierarchicalDataTemplate DataType="{x:Type VM:SelectActivityViewModel}" ItemsSource="{Binding ToolsViewModelCollection}"
                                     >
                                <StackPanel Orientation="Horizontal">
                                    <Image Source="./resources/New_Package.png" Width="15" Height="15"/>
                                    <TextBlock Text="{Binding Header}"></TextBlock>
                                </StackPanel>
                                <HierarchicalDataTemplate.ItemTemplate>
                                    <HierarchicalDataTemplate DataType="{x:Type VM:ToolsViewModel}" ItemsSource="{Binding SheetsViewModelBaseCollection}">
                                        <StackPanel Orientation="Horizontal">
                                            <Image Source="./resources/New_Package.png" Width="15" Height="15"/>
                                            <TextBlock Text="{Binding Header}"></TextBlock>
                                        </StackPanel>
                                        <HierarchicalDataTemplate.ItemTemplate>
                                            <HierarchicalDataTemplate x:Name="LastLevel" DataType="{x:Type VM:ViewModelBase}" ItemsSource="{Binding FeaturesViewModelCollection}">
                                                <StackPanel Orientation="Horizontal">
                                                    <Image Source="./resources/file.png" Width="15" Height="15"/>
                                                    <TextBlock Text="{Binding Header}"/>
                                                </StackPanel>
                                            </HierarchicalDataTemplate>
                                        </HierarchicalDataTemplate.ItemTemplate>

                                    </HierarchicalDataTemplate>
                                </HierarchicalDataTemplate.ItemTemplate>
                            </HierarchicalDataTemplate>
                        </HierarchicalDataTemplate.ItemTemplate>
                    </HierarchicalDataTemplate>
                </TreeView.ItemTemplate>

类结构: (ViewModelBase扩展到了所有类)

Class Structure: (ViewModelBase is extended to all classes)

  • ProjectViewModel-具有SelectActivityViewModelCollection =(ObservableCollection(SelectActivityViewModel))
  • SelectActivityViewModel-具有ToolsViewModelCollection =(OC(ToolsViewModel))
  • ToolsViewModel-具有SheetsViewModelBaseCollection和FeaturesViewModelCollection =(OC(ViewModelBase)和OC(FeaturesViewModel))
  • FeaturesViewModel-具有UseCaseViewModelCollection =(OC(UseCaseViewModel))
  • 在ToolsViewModel中,我使用SheetsViewModelBaseCollection来存储Child1/Child2/.../Child5
  • 和FeaturesViewModelCollection-存储Child1_Of_Child5/Child2_Of_Child5/../Child(n)_Of_Child5
  • 由于我已经将ViewModelBase扩展到所有类,因此我正在使用OC(ViewModelBase)来存储不同的图纸(即SheetsViewModelCollection中的图纸). 注意:

  • ProjectViewModel - has SelectActivityViewModelCollection = (ObservableCollection(SelectActivityViewModel))
  • SelectActivityViewModel - has ToolsViewModelCollection = (OC(ToolsViewModel))
  • ToolsViewModel - has SheetsViewModelBaseCollection and FeaturesViewModelCollection = (OC(ViewModelBase) and OC(FeaturesViewModel))
  • FeaturesViewModel - has UseCaseViewModelCollection = (OC(UseCaseViewModel))
  • In ToolsViewModel I am using SheetsViewModelBaseCollection to store Child1/Child2/.../Child5
  • and FeaturesViewModelCollection - to store Child1_Of_Child5/Child2_Of_Child5/../Child(n)_Of_Child5
  • EDIT : As i have extended ViewModelBase to all classes, i am using OC(ViewModelBase) to store different sheets(.i.e.,in SheetsViewModelCollection). Note:

  1. 不使用数据库:使用序列化和反序列化
  2. WPF:遵循MVVM模式

图像显示了各个类的完整TreeView和OC

推荐答案

我试图在示例项目中重现您的问题.

I have tried to reproduce your problem in a sample project.

根据您的描述,ToolsViewModel具有两个集合(SheetsViewModel和FeaturesViewModel的集合). 如果要在树中显示这两个对象,则必须创建一个包含所有这些对象的单个集合.

According to your description, ToolsViewModel has two collections (of SheetsViewModel and of FeaturesViewModel). If you want to show both of these in the tree, you will have to make a single collection containing all of these objects.

我创建了一个名为ViewModelCollection的附加集合,以显示其工作方式.

I have created an additional collection called ViewModelCollection to show how this might work.

对于我的测试,我定义了以下类:

For my tests, I have defined classes as follows:

using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace TreeViewTest
{
  class ViewModelBase
  {
  }

  class ViewModel
  {
    public ObservableCollection<ProjectViewModel>  ProjectViewModelCollection { get; private set; }

    public ViewModel ( )
    {
      ProjectViewModelCollection = new ObservableCollection<ProjectViewModel>() ;
      ProjectViewModelCollection.Add ( new ProjectViewModel() ) ;
      ProjectViewModelCollection.Add ( new ProjectViewModel() ) ;
    }
  }

  class ProjectViewModel
  {
    public ObservableCollection<SelectActivityViewModel>  SelectActivityViewModelCollection { get; private set; }
    public string Header { get ; } = "ProjectViewModel" ;

    public ProjectViewModel ( )
    {
      SelectActivityViewModelCollection = new ObservableCollection<SelectActivityViewModel>() ;
      SelectActivityViewModelCollection.Add ( new SelectActivityViewModel() ) ;
      SelectActivityViewModelCollection.Add ( new SelectActivityViewModel() ) ;
    }

  }

  class SelectActivityViewModel
  {
    public ObservableCollection<ToolsViewModel>  ToolsViewModelCollection  { get; private set; }
    public string Header { get ; } = "SelectActivityViewModel" ;

    public SelectActivityViewModel ( )
    {
      ToolsViewModelCollection = new ObservableCollection<ToolsViewModel>() ;
      ToolsViewModelCollection.Add ( new ToolsViewModel() ) ;
      ToolsViewModelCollection.Add ( new ToolsViewModel() ) ;
    }
  }

  class ToolsViewModel
  {
    public ObservableCollection<SheetsViewModel>    SheetsViewModelCollection    { get; private set; }
    public ObservableCollection<FeaturesViewModel>  FeaturesViewModelCollection  { get; private set; }
    public ObservableCollection<ViewModelBase>      ViewModelCollection          { get; private set; }
    public string Header { get ; } = "ToolsViewModel" ;

    public ToolsViewModel ( )
    {
      SheetsViewModelCollection = new ObservableCollection<SheetsViewModel>() ;
      SheetsViewModelCollection.Add ( new SheetsViewModel() ) ;
      SheetsViewModelCollection.Add ( new SheetsViewModel() ) ;

      FeaturesViewModelCollection = new ObservableCollection<FeaturesViewModel>() ;
      FeaturesViewModelCollection.Add ( new FeaturesViewModel() ) ;
      FeaturesViewModelCollection.Add ( new FeaturesViewModel() ) ;

      // Make a single collection with all children
      ViewModelCollection = new ObservableCollection<ViewModelBase>() ;
      foreach ( var o in SheetsViewModelCollection )
        ViewModelCollection.Add ( o ) ;
      foreach ( var o in FeaturesViewModelCollection )
        ViewModelCollection.Add ( o ) ;
    }
  }

  class SheetsViewModel : ViewModelBase
  {
    public string Header { get ; } = "SheetsViewModel" ;
  }

  class FeaturesViewModel : ViewModelBase
  {
    public ObservableCollection<UseCaseViewModel>  UseCaseViewModelCollection   { get; private set; }
    public string Header { get ; } = "FeaturesViewModel" ;

    public FeaturesViewModel ( )
    {
      UseCaseViewModelCollection = new ObservableCollection<UseCaseViewModel>() ;
      UseCaseViewModelCollection.Add ( new UseCaseViewModel() ) ;
      UseCaseViewModelCollection.Add ( new UseCaseViewModel() ) ;
    }
  }

  class UseCaseViewModel
  {
    public string Header { get ; } = "UseCaseViewModel" ;
  }
}

我对XAML进行了一些更改:

I have made some changes to the XAML:

(1)我为以下内容定义了其他模板:

(1) I have defined additional templates for:

  • FeaturesViewMode
  • SheetsViewModel
  • UseCaseViewModel

(2)我已经将HierarchicalDataTemplate定义为没有任何嵌套的资源.

(2) I have defined the HierarchicalDataTemplate as resources without any kind of nesting.

这是个人喜好.我认为您使用HierarchicalDataTemplate.ItemTemplate的方法也可以.

This is personal preference. I think that your approach with HierarchicalDataTemplate.ItemTemplate also works.

<Window x:Class="TreeViewTest.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        xmlns:VM="clr-namespace:TreeViewTest"
        mc:Ignorable="d"
        Title="MainWindow" Height="450" Width="800">
  <Grid>

    <TreeView ItemsSource="{Binding ProjectViewModelCollection}">

      <TreeView.Resources>

        <HierarchicalDataTemplate DataType="{x:Type VM:ProjectViewModel}" ItemsSource="{Binding SelectActivityViewModelCollection}">
          <StackPanel Orientation="Horizontal">
            <Image Source="./resources/New_Package.png" Width="15" Height="15"/>
            <TextBlock Text="{Binding Header}"></TextBlock>
          </StackPanel>
        </HierarchicalDataTemplate>

        <HierarchicalDataTemplate DataType="{x:Type VM:SelectActivityViewModel}" ItemsSource="{Binding ToolsViewModelCollection}">
          <StackPanel Orientation="Horizontal">
            <Image Source="./resources/New_Package.png" Width="15" Height="15"/>
            <TextBlock Text="{Binding Header}"></TextBlock>
          </StackPanel>
        </HierarchicalDataTemplate>

        <HierarchicalDataTemplate DataType="{x:Type VM:ToolsViewModel}" ItemsSource="{Binding ViewModelCollection}">
          <StackPanel Orientation="Horizontal">
            <Image Source="./resources/New_Package.png" Width="15" Height="15"/>
            <TextBlock Text="{Binding Header}"></TextBlock>
          </StackPanel>
        </HierarchicalDataTemplate>

        <HierarchicalDataTemplate DataType="{x:Type VM:FeaturesViewModel }" ItemsSource="{Binding UseCaseViewModelCollection}">
          <StackPanel Orientation="Horizontal">
            <Image Source="./resources/New_Package.png" Width="15" Height="15"/>
            <TextBlock Text="{Binding Header}"></TextBlock>
          </StackPanel>
        </HierarchicalDataTemplate>

        <HierarchicalDataTemplate DataType="{x:Type VM:SheetsViewModel}">
          <StackPanel Orientation="Horizontal">
            <Image Source="./resources/New_Package.png" Width="15" Height="15"/>
            <TextBlock Text="{Binding Header}"></TextBlock>
          </StackPanel>
        </HierarchicalDataTemplate>

        <HierarchicalDataTemplate DataType="{x:Type VM:UseCaseViewModel}">
          <StackPanel Orientation="Horizontal">
            <Image Source="./resources/New_Package.png" Width="15" Height="15"/>
            <TextBlock Text="{Binding Header}"></TextBlock>
          </StackPanel>
        </HierarchicalDataTemplate>

      </TreeView.Resources>
    </TreeView>

  </Grid>
</Window>

DataContext在后面的代码中初始化如下.还有其他方法可以做到这一点.

The DataContext is initialised in code behind as follows. There are other ways to do this.

public MainWindow ( )
{
  DataContext = new ViewModel() ;
  InitializeComponent ();
}

我能够在五个级别上显示所有六种类型,如下所示:

I was able to show all six types on five levels as shown below:

这篇关于将自定义类作为TreeViewItem添加到TreeView WPF的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆