使用MVVM在WPF中选择TreeView节点上填充列表框

时间:2018-12-15 18:01:29

标签: wpf mvvm treeview

我正在WPF中开发一个应用程序,我想在其中选择TreeView的一个节点时填充一个ListBox。我已经使用MVVM模式填充了TreeView。它实际上包含驱动器(C:\,D:...)及其相应的子文件夹。子文件夹是节点。选择这些节点后,相应的文件应显示在列表框中。我知道用C#代码获取文件夹中的所有文件,我也实现了相同的代码。但是,我没有任何映射它们的线索,因此在选择节点时,它们中的文件应反映在ListBox中。

在这方面可以帮助我吗?该应用程序正在以MVVM模式开发,而我本身也需要相同的模式。

3 个答案:

答案 0 :(得分:0)

首先将Files集合类添加到您的文件夹类(用于树形视图)

public class FolderItem
{
    // other class code

    private ObservableCollection<File> _Files = null;

    public ObservableCollection<File> Files
    {
        get
        {
            if (_Files == null) _Files = GetFiles();
            return _Files;
        }
        set
        {
            _Files = value;
        }
    }

}

然后将列表框绑定到选定的树视图项目。

<ListBox ItemsSource="{Binding ElementName=myTreeView, Path=SelectedItem.Files}"/>

答案 1 :(得分:0)

您可能有很多文件和文件夹,所以我认为我倾向于尽可能多地延迟加载。

这意味着viewmodel最初不需要遍历整个硬盘驱动器,但是当selecteditem更改时,您需要采取某种措施。

您不能将selecteditem绑定到视图模型,因为它是只读的。

因此,我将使用以下行为: Data binding to SelectedItem in a WPF Treeview

使用它绑定一个SelectedFolder。 在SelectedFolder的设置器中,获取该文件夹的文件夹和文件列表,并填充两个集合。一个是该选定项的子集合-用于其文件夹。 另一个是observableCollection,供文件在列表框中查看。 使该属性变为实,并实现inotifyproprtychanged,以便在将其设置为新集合时通知ui。 将该集合绑定到列表框的itemssource。

答案 2 :(得分:0)

基本上,MVVM模式使用三个层:

  1. 模型:基本上,它包含模型类和用于获取和操纵数据信息的业务逻辑。
  2. ViewModel:它充当模型和视图之间的中间层,它附加到不同的视图。
  3. 视图:应用程序的不同视图。

下面是一个示例,该示例如何用驱动器和文件列表填充窗口。

BindableBaseViewModel类

namespace TalkRepeater.ViewModel
{
    public class BindableBaseViewModel : DependencyObject,INotifyPropertyChanged
    {
        protected virtual void SetProperty<T>(ref T member, T val,[CallerMemberName] string propertyName = null)
        {
           if (object.Equals(member, val)) return;
           member = val;
           PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
        }

        protected virtual void OnPropertyChanged(string propertyName)
        {
          PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
        }

        public event PropertyChangedEventHandler PropertyChanged = delegate { };

    }
}

类ViewModel

public  class FoldersControlViewModel : BindableBaseViewModel
{   
        private ObservableCollection<Folders> _listFolders;
    private ObservableCollection<Folders> _listFiles;

        public FoldersControlViewModel()
        {
       FoldersBusinessObject vbo =new FoldersBusinessObject()
            vbo.FillFolders();
        ListFolders = FileBusinessObject.ListFolders;
    }

        public ObservableCollection<Folders> ListFolders
        {
            get
            {
              return _listFolders;
            }
            set
            {
              _listFolders = value;              
              OnPropertyChanged("ListFolders");               
            }
        }

        public ObservableCollection<Folders> ListFiles
        {
            get
            {
              return _listFiles;
            }
            set
            {
              _listFiles = value;              
              OnPropertyChanged("ListFiles");               
            }
        }   

    Public void FillListFiles()
    {
        /*ListFiles= Cod to fill ListFiles*/
    }   
}

BusinessObject类

public class FoldersBusinessObject
{
     private ObservableCollection<Folders> _ListFolders;

     public void FillFolders()
     {
    /* ListFolders= Code To fill the collection ListFolders   */
     } 

     public ObservableCollection<Folders> ListFolders
     {
            get
            {
               return _ListFolders;
            }
            set
            {
              _ListFolders = value;
            }
        }
}

文件夹视图

<Window x:Class="Foldersview"
   xmlns = "http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
   xmlns:x = "http://schemas.microsoft.com/winfx/2006/xaml" 
   xmlns:mc = "http://schemas.openxmlformats.org/markup-compatibility/2006" 
   xmlns:d = "http://schemas.microsoft.com/expression/blend/2008" 
   d:DesignHeight = "300" Width="1007" Height="606">

    <Grid Margin="10"  >

        <Canvas x:Name="canvasFolders" Margin="-10,0,912,10">
            <TreeView x:Name="TreevFolders" ItemsSource="{Binding Path=ListFolders, Mode=TwoWay}" Canvas.Top="5" Canvas.Left="17" Width="142" Height="561" 
                 SelectedItemChanged="TreevFolders_SelectedItemChanged" >               

                <TreeView.ItemTemplate>
                    <HierarchicalDataTemplate ItemsSource="{Binding Path=ListFolders}">                  
                        <TextBlock Text="{Binding Path=FileName}">    
                        </TextBlock>
                    </HierarchicalDataTemplate>
                </TreeView.ItemTemplate>

            </TreeView>
        </Canvas>

        <Canvas Margin="159,10,0,10">
            <Listview x:Name="Listview1" ItemsSource="{Binding ListFiles, Mode=TwoWay}"  >

            </Listview>
        </Canvas>

    </Grid>

</Window>

类文件夹后面的查看代码

public partial class Foldersview : Window
  {
        private void TreevFolders_SelectedItemChanged(object sender, RoutedPropertyChangedEventArgs<object> e)
        {            
               FoldersControlViewModel vmd = (FoldersControlViewModel)this.DataContext;
               vmd.FillListFiles ();              
        }
}

类主窗口

public class MainWindowViewModel : BindableBase
{
      private FoldersControlViewModel FoldersviewModel;
      public MainWindowViewModel()
      { 
      FoldersviewModel = new FoldersControlViewModel();                  
          Foldersview=new Foldersview();
      Foldersview.Datacontext=FoldersviewModel;
        }      
}

Cordialy