C# ObservableCollection 没有出现在 MVVM 的 TreeView 中

C# ObservableCollection dosen't appear in TreeView by MVVM

所以我有一个包含 NameCodeIdList 的集合,节点类型为 ServiceTypeDto,就像这个模型:

public class ServiceTypeDto
{
   public long Id
   public string Code
   public string Name
   public List<ServiceTypeDto> ChildrenList
}

我有一个方法 returns ServiceTypeDto 的列表,像这样:

我有一个 ChildernList 暴露了 ServiceTypeDtos。

这就是我在 ViewModel 中尝试执行此操作的方式:

using System.Collections.Generic;
using System.Collections.ObjectModel;

using ServiceTypeService.Dto;
using ServiceTypeService.Interface;

using ShowServiceType.Interfaces;
using ShowServiceType.Utils;

namespace ShowServiceType.ViewModel
{
   class MainWindowViewModel : ViewModelBase
   {
      public string _name, _code;
      public long _id;
      public List<ServiceTypeDto> _childrenList = new List<ServiceTypeDto>();

      /// <summary>
      /// Create Services for work
      /// </summary>
      ILogService Log => Service.CreateLog();
      IExceptionHandler ExceptionHandler => Service.CreateExeptionHandler();
      IServiceType ServiceType => Service.CreateGetServiceType();


      public ObservableCollection<ServiceTypeDto> _servicesCollection;

      public MainWindowViewModel()
      {
         ServiceConfig.Initialization();
         var _services = ServiceType.GetServiceTypesTree();
         _servicesCollection = new ObservableCollection<ServiceTypeDto>();

         //This is convert to ObservableCollection my List<> =)
         foreach (var item in _services)
            _servicesCollection.Add(item);
      }

      public long ID
      {
         get => _id;
         set
         {
            _id = value;
            OnPropertyChanged("ID");
         }
      }
      public string Code
      {
         get => _code;
         set
         {
            _code = value;
            OnPropertyChanged("Code");
         }
      }
      public string Name
      {
         get => _name;
         set
         {
            _name = value;
            OnPropertyChanged("Name");
         }
      }
      public List<ServiceTypeDto> Children
      {
         get => _childrenList;
         set
         {
            _childrenList = value;
            OnPropertyChanged("Children");
         }
      }
   }
}

我的 ViewModelBase 类型:

public class ViewModelBase : INotifyPropertyChanged
{
   public event PropertyChangedEventHandler PropertyChanged;
    
   public void OnPropertyChanged( string propname ) => PropertyChanged?.Invoke(this , new PropertyChangedEventArgs(propname));
}

我的主要代码隐藏 window:

public MainWindow()
{
   InitializeComponent();
   ServiceConfig.Initialization();
   DataContext = new MainWindowViewModel();
}

最后这是视图的XAML。

<Grid Grid.Row="1">
   <ScrollViewer HorizontalScrollBarVisibility="Auto" VerticalScrollBarVisibility="Visible">
      <TreeView>
         <TreeView.ItemTemplate>
            <HierarchicalDataTemplate ItemsSource="{Binding Path=Children}">
               <StackPanel FlowDirection="LeftToRight" Orientation="Horizontal">
                  <TextBlock Text="{Binding ID}" />
                  <TextBlock Text="{Binding Code}" />
                  <TextBlock Text="{Binding Name}" />
               </StackPanel>
            </HierarchicalDataTemplate>
         </TreeView.ItemTemplate>
      </TreeView>
   </ScrollViewer>
</Grid>

ObservableCollection 没有出现在 TreeView 中。怎么了?

您的视图和视图模型中存在多个问题:

  • TreeView没有绑定任何东西,将它的ItemSource绑定到Children,否则不会显示任何项目
  • HierarchicalDataTemplateItemsSource 必须绑定到您的 ServiceTypeDto 中的子集合,即 ChildrenList,而不是 Children
  • 您没有填充 Children 集合(或其后备集合 _childrenList ),因此它是空的。
  • 您将项目添加到 _servicesCollection,但它也未被使用
  • ServiceTypeDto 未实现 INotifyPropertyChanged,因此属性更改不会反映在用户界面中
  • ServiceTypeDto 中的
  • ChildrenList 不是 ObservableCollection,因此添加或删除项目也不会反映在用户界面中

您应该考虑对 属性 使用 Children 和对支持字段使用 _children 这样的命名约定,以提高代码的可读性,参考 here关于 C# 中的命名。

1) 好的,我在 View 上绑定了我的 TreeView.ItemSourceChildrenList

2) 我不明白我如何将集合 ServiceTypeDto 中的 ChildList 绑定到我的 ObserveCollection,我如何理解索引我 select 在 UI ?

    public List<ServiceTypeDto> ChildrenList
        {
            get => _servicesCollection[0].ChildrenList; // ? index ?
            set
            {
                _servicesCollection[0].ChildrenList = value; // ? 0 ?
                OnPropertyChanged("ChildrenList");
            }
        }
    public string Name
        {
            get => _servicesCollection[0].Name; // ? 0 ?
            set
            {
                _servicesCollection[0].Name = value; // ? 
                OnPropertyChanged("Name");
            }
        }

其他属性必须知道要从 _servicesCollection[index].Name 请求正确数据的索引?

3) 我无法根据任务条件将 ServiceTypeDto 中的 ChildrenList 更改为 ObserveCollection out off dll。 这只是参考。

在此之后,我不知道如何使用 0 索引! 但是只工作第一个节点不会出现在 subList

中的其他列表
<Grid Grid.Row="1">
            <ScrollViewer HorizontalScrollBarVisibility="Auto" VerticalScrollBarVisibility="Visible">
                <TreeView ItemsSource="{Binding Path=ChildrenList}">
                    <TreeView.ItemTemplate>
                        <HierarchicalDataTemplate ItemsSource="{Binding Path=ChildrenList}">
                            <StackPanel FlowDirection="LeftToRight" Orientation="Horizontal">
                                <TextBlock Text="{Binding ID}" />
                                <TextBlock Text="{Binding Code}" />
                                <TextBlock Text="{Binding Name}" />
                            </StackPanel>
                        </HierarchicalDataTemplate>
                    </TreeView.ItemTemplate>
                </TreeView>
            </ScrollViewer>
        </Grid>