Добавление пользовательского класса в виде TreeViewItem в TreeView WPF - PullRequest
0 голосов
/ 04 марта 2019

У меня есть сценарий, в котором мой TreeView выглядит следующим образом:

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

Я могу связать ObservableCollection до Child1 / Child2 /../ Child5, используя HierarchicalDataTemplate.Хотя я могу добавить Child1_Of_Child5 в Child5 ObservableCollection (видно в режиме отладки), то же самое не отражается в пользовательском интерфейсе / древовидном представлении.

Ниже приведен мой код XAML:

<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 распространяется на все классы)

  • ProjectViewModel - имеет SelectActivityViewModelCollection = (ObservableCollection (SelectActivityViewModel)) *
  • SelectActivityViewModel - имеет ToolsViewModelCollection = * OC (ToolsViewModel) ** ToolsViewModel - имеет SheetsViewModelBaseCollection и FeaturesViewModelCollection = (OC (ViewModelBase) и OC (FeaturesViewModel)) *
  • FeaturesViewModel - имеет UseCaseViewModelCollection = (OC (UseCaseViewModel), метод InSize для использования с другими объектами)Child1 / Child2 /.../ Child5
  • и FeaturesViewModelCollection - для хранения Child1_Of_Child5 / Child2_Of_Child5 /../ Child (n) _Of_Child5
  • РЕДАКТИРОВАТЬ: поскольку я расширил ViewModelBase для всехклассы, я использую OC (ViewModelBase) для хранения разных листов (.ie, в SheetsViewModelCollection).Примечание:

    1. База данных не используется: используется сериализация и десериализация
    2. WPF: используется шаблон MVVM

Изображение показывает полный TreeView и OC соответствующих классов

1 Ответ

0 голосов
/ 05 марта 2019

Я попытался воспроизвести вашу проблему в примере проекта.

Согласно вашему описанию, ToolsViewModel имеет две коллекции (SheetsViewModel и FeaturesViewModel).Если вы хотите отобразить оба из них в дереве, вам придется создать одну коллекцию, содержащую все эти объекты.

Я создал дополнительную коллекцию под названием ViewModelCollection, чтобы показать, как это может работать.

Для моих тестов я определил классы следующим образом:

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:

(1) Я определил дополнительные шаблоны для:

  • FeaturesViewMode
  • SheetsViewModel
  • UseCaseViewModel

(2) Я определил HierarchicalDataTemplate как ресурсы без какого-либо вложения.

Это личное предпочтение.Я думаю, что ваш подход с HierarchicalDataTemplate.ItemTemplate также работает.

<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 инициализируется в коде ниже следующим образом.Есть и другие способы сделать это.

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

Мне удалось показать все шесть типов на пяти уровнях, как показано ниже:

Screen shot

...