桌面应用开发的日子(二):实现文件资源管理列表树加载

  • A+
所属分类:.NET技术
摘要

已矣乎!寓形宇内复几时?曷不委心任去留?胡为乎遑遑欲何之?富贵非吾愿,帝乡不可期。怀良辰以孤往,或植杖而耘耔。登东皋以舒啸,临清流而赋诗。聊乘化以归尽,乐夫天命复奚疑!————《归去来兮辞并序》·陶渊明

已矣乎!寓形宇内复几时?曷不委心任去留?胡为乎遑遑欲何之?富贵非吾愿,帝乡不可期。怀良辰以孤往,或植杖而耘耔。登东皋以舒啸,临清流而赋诗。聊乘化以归尽,乐夫天命复奚疑!————《归去来兮辞并序》·陶渊明

实现效果
桌面应用开发的日子(二):实现文件资源管理列表树加载

获取本地逻辑驱动器、文件夹、文件

Directory.GetLogicalDrives(); Directory.GetDirectories(fullPath); // 返回指定目录中的子目录 Directory.GetFiles(fullPath); // 返回指定目录中的文件  // 截取文件或文件夹名称 public static string GetFileFolderName(string path) {     if (string.IsNullOrEmpty(path))         return string.Empty;     path = path.Replace("/", "\");      var lastIndex = path.LastIndexOf("\");     if (lastIndex <= 0)         return path;      return path.Substring(lastIndex + 1); } 

通过mvvm模式,实现后台数据与ui进行绑定,下面是树UI结构定义和实体,视图模型的定义

<TreeView x:Name="FolderTreeView" Grid.Row="1" ItemsSource="{Binding Items}">     <TreeView.ItemContainerStyle>         <Style TargetType="{x:Type TreeViewItem}">             <Setter Property="IsExpanded" Value="{Binding IsExpanded,Mode=TwoWay}"/>         </Style>     </TreeView.ItemContainerStyle>     <TreeView.ItemTemplate>         <HierarchicalDataTemplate ItemsSource="{Binding Children}">             <StackPanel Orientation="Horizontal">                 <TextBlock Margin="3" FontFamily="{StaticResource IconFont}" FontSize="26" Foreground="{Binding IconColor}" Text="{Binding Icon}" />                 <TextBlock  VerticalAlignment="Center" FontSize="18" Text="{Binding Name}"/>             </StackPanel>         </HierarchicalDataTemplate>     </TreeView.ItemTemplate> </TreeView> 
public class DirectoryItem {     public string FullPath { get; set; }     public DirectoryItemType Type { get; set; }     public string Name     {         get         {             return this.Type == DirectoryItemType.Drive ?               this.FullPath :               DirectoryStructure.GetFileFolderName(this.FullPath);         }     }     public string Icon { get; set; }     public Brush IconColor { get; set; } } 
public class DirectoryItemViewModel : BaseViewModel {     /// <summary>     /// 全路径     /// </summary>     public string FullPath { get; set; }      /// <summary>     /// 成员类型     /// </summary>     public DirectoryItemType Type { get; set; }      /// <summary>     /// 成员名称     /// </summary>     public string Name     {         get         {             return this.Type == DirectoryItemType.Drive ?               this.FullPath :               DirectoryStructure.GetFileFolderName(this.FullPath);         }     }      /// <summary>     /// 成员图标     /// </summary>     public string Icon { get; set; }      /// <summary>     /// 图标颜色     /// </summary>     public Brush IconColor { get; set; }      /// <summary>     /// 子成员     /// </summary>     public ObservableCollection<DirectoryItemViewModel> Children { get; set; }      /// <summary>     /// 表示成员是否可以展开     /// </summary>     public bool CanExpend { get { return this.Type != DirectoryItemType.File; } }      /// <summary>     /// 展开/收缩的处理     /// </summary>     public bool IsExpanded     {         get         {             return this.Children?.Count(x => x != null) > 0;         }         set         {             if (value)                 Expand();             else                 ClearChildren();         }     }       public ICommand ExpandCommand { get; set; }      public DirectoryItemViewModel()     {         this.ExpandCommand = new RelayCommand(Expand);         this.ClearChildren();     }      private void ClearChildren()     {         this.Children = new ObservableCollection<DirectoryItemViewModel>();         if (this.Type != DirectoryItemType.File)             this.Children.Add(null);     }      /// <summary>     /// 展开目录并找到所有子成员     /// </summary>     private void Expand()     {         if (this.Type == DirectoryItemType.File)             return;         var children = DirectoryStructure.GetDirectContents(this.FullPath);         var selector = children.Select(x => new DirectoryItemViewModel()         {             FullPath = x.FullPath,             Type = x.Type,             Icon = x.Icon,             IconColor = x.IconColor         });         this.Children = new ObservableCollection<DirectoryItemViewModel>(selector);     } } public class DirectoryStructureViewModel : BaseViewModel {     public ObservableCollection<DirectoryItemViewModel> Items { get; set; }      public DirectoryStructureViewModel()     {         var children = DirectoryStructure.GetLogicalDrives();         var selector = children.Select(x =>         new DirectoryItemViewModel()         {             FullPath = x.FullPath,             Type = x.Type,             Icon = x.Icon,             IconColor = x.IconColor         });         this.Items = new ObservableCollection<DirectoryItemViewModel>(selector);     } } 

构建基类视图模型

[AddINotifyPropertyChangedInterface] public class BaseViewModel : INotifyPropertyChanged {     public event PropertyChangedEventHandler PropertyChanged=(sender, e)=>{}; //数据变化时通知前端 } 

通过命令,点击逻辑器或文件夹时,加载子元素

    public class RelayCommand : ICommand     {         private Action action;          public event EventHandler CanExecuteChanged = (sender, e) => { };          public RelayCommand(Action action)         {             this.action = action;         }          public bool CanExecute(object parameter)         {             return true;         }          public void Execute(object parameter)         {             action();         }     } 

相关参考:
https://github.com/Fody/PropertyChanged
https://docs.microsoft.com/zh-cn/dotnet/api/system.windows.controls.treeview?view=net-5.0
https://docs.microsoft.com/zh-cn/dotnet/api/system.componentmodel.inotifypropertychanged?view=net-5.0
https://docs.microsoft.com/zh-cn/dotnet/api/system.windows.input.icommand?view=net-5.0