zoukankan      html  css  js  c++  java
  • 桌面应用开发的日子(二):实现文件资源管理列表树加载

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

    实现效果

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

    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

  • 相关阅读:
    记录一些经常被忽略的结论
    Eclipse 各种问题解决记录
    Feign 动态URL 解决记录
    Nacos 启动失败
    多git账号配置解决方案
    记一次java.lang.StackOverflowError
    StringBuilder 以及 StringBuffer默认大小与扩容
    MySQL索引背后的数据结构及原理
    我没有高并发项目经验,但是面试的时候经常被问到高并发、性能调优方面的问题,有什么办法可以解决吗?
    istio 学习之 手动注入sidecar
  • 原文地址:https://www.cnblogs.com/zhuanghamiao/p/wpf-treeview.html
Copyright © 2011-2022 走看看