已矣乎!寓形宇内复几时?曷不委心任去留?胡为乎遑遑欲何之?富贵非吾愿,帝乡不可期。怀良辰以孤往,或植杖而耘耔。登东皋以舒啸,临清流而赋诗。聊乘化以归尽,乐夫天命复奚疑!————《归去来兮辞并序》·陶渊明
实现效果
获取本地逻辑驱动器、文件夹、文件
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