今天我来写一篇关于利用WPF来实现Windows的资源管理器功能,当然只是局部实现这个功能,因为在很多时候我们需要来实现对本机资源的管理,当然我们可以使用OpenFileDialog dialog = new OpenFileDialog()这个Microsoft.Win32命名空间下的这个类来实现一些资源查找和导入的功能,但是在很多时候我们可能需要更多的功能,并且希望能够集成到我们自己的项目中,但是我们这个时候就不得不自己来写一套来集成到我们的软件中去了,因为OpenFileDialog这个是无法作为一个UserControl加入到我们的项目中的,当然我们只是实现了其中的一部分功能,因为Windows的资源管理器也是一个重量级的应用,也是十分庞大和复杂的,这里只是通过这个Demo来加深对WPF的MVVM模式及软件基本功的巩固。
在正式介绍整体框架之前,首先来看看整体的结构,从而对其有一个大概的了解。
图一 整体界面描述
整个界面从大的方面来说主要包括三个方面:1 文件及文件夹显示区域、2 导航区域、3 路径显示区域,其实在整个界面中,2和3都是围绕1来进行操作的,三个区域之间的耦合性其实是非常高的,所以常规的做法就是三个部分分为三个UserControl,并且同时绑定到一个ViewModel中,这样整个层次也就比较清晰了,缺点是一个ViewModel中代码太多,职责非常大,所以在这个DEMO中尝试将三个部分分开,三个ViewModel来操作三个View里面的内容,整个实现下来其实也有一些不足之处,那就是容易将问题复杂化,很多在一个类中就能够完成的工作,最终要通过各种类与类之间的耦合来完成,所以通过这个DEMO希望自己能够多一些思考,从而在软件的设计中能够再多一些经验,能够把握好软件粒度的问题,下面就软件的具体内容来深入分析一下。
第一部分:FileList
这个部分是整个文件和文件夹的显示部分,再三权衡下,决定采用自定义DataGrid的方式来展现整个部分。
<UserControl x:Class="FileSelectorDemo.Views.FileList" 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:converter="clr-namespace:FileSelectorDemo.Converters" xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:defines="clr-namespace:FileSelectorDemo.Defines" xmlns:local="clr-namespace:FileSelectorDemo.Views" mc:Ignorable="d" d:DesignHeight="300" d:DesignWidth="300"> <UserControl.Resources> <converter:CountToVisibilityConverter x:Key="CountToVisibilityConverter"></converter:CountToVisibilityConverter> <converter:TypeToVisibleConverter x:Key="TypeToVisibleConverter"></converter:TypeToVisibleConverter> <converter:TypeToCollapsedConverter x:Key="TypeToCollapsedConverter"></converter:TypeToCollapsedConverter> <converter:CollectionSelectedCountConverter x:Key="CollectionSelectedCountConverter"></converter:CollectionSelectedCountConverter> </UserControl.Resources> <Grid> <ScrollViewer HorizontalScrollBarVisibility="Auto" VerticalScrollBarVisibility="Auto"> <Grid> <StackPanel Orientation="Vertical"> <DataGrid x:Name="fileList" HorizontalAlignment="Stretch" VerticalAlignment="Stretch" defines:MouseDoubleClick.Command="{Binding OpenCurrentDirectory}" defines:MouseDoubleClick.CommandParameter="{Binding SelectedItem,RelativeSource={RelativeSource Self}}" IsReadOnly="True" defines:MouseLeftButtonUpClick.Command="{Binding SelectCurrentFileListItem}" ItemsSource="{Binding CurrentFileList}" CanUserAddRows="False" AutoGenerateColumns="False" GridLinesVisibility="None"> <DataGrid.Columns> <DataGridTemplateColumn MinWidth="60"> <DataGridTemplateColumn.Header> <CheckBox Content="全选" Margin="2" FontSize="12" HorizontalAlignment="Center" VerticalAlignment="Center" IsChecked="{Binding DataContext.IsStateCheckAll,RelativeSource={RelativeSource Mode=FindAncestor,AncestorType={x:Type DataGrid}}}"></CheckBox> </DataGridTemplateColumn.Header> <DataGridTemplateColumn.CellTemplate> <DataTemplate> <Grid HorizontalAlignment="Center" VerticalAlignment="Center"> <TextBlock Text="不可选" FontSize="12" Foreground="Black" Visibility="{Binding CurrentType,Converter={StaticResource TypeToCollapsedConverter}}" HorizontalAlignment="Left" VerticalAlignment="Center" ></TextBlock> <CheckBox IsChecked="{Binding IsSelected,Mode=TwoWay,UpdateSourceTrigger=PropertyChanged}" IsThreeState="False" IsHitTestVisible="False" Visibility="{Binding CurrentType,Converter={StaticResource TypeToVisibleConverter}}" HorizontalAlignment="Left" VerticalAlignment="Center" ToolTip="点击选中当前对象"></CheckBox> </Grid> </DataTemplate> </DataGridTemplateColumn.CellTemplate> </DataGridTemplateColumn> <DataGridTemplateColumn Header="名称" > <DataGridTemplateColumn.CellTemplate> <DataTemplate> <StackPanel Orientation="Horizontal" HorizontalAlignment="Left" VerticalAlignment="Center"> <Image Source="{Binding Icon}" Margin="2" HorizontalAlignment="Center" VerticalAlignment="Center"></Image> <TextBlock Text="{Binding Name}" Margin="2" HorizontalAlignment="Center" VerticalAlignment="Center"></TextBlock> </StackPanel> </DataTemplate> </DataGridTemplateColumn.CellTemplate> </DataGridTemplateColumn> <DataGridTextColumn Header="修改日期" Binding="{Binding CreateTime}"/> <DataGridTextColumn Header="类型" Binding="{Binding CurrentType}"/> <DataGridTextColumn Header="大小" Binding="{Binding Size}"/> </DataGrid.Columns> </DataGrid> <TextBlock Margin="2 5" HorizontalAlignment="Left" VerticalAlignment="Center" > <Run>总共 </Run> <Run Text="{Binding CurrentFileList.Count,Mode=OneWay}"></Run> <Run> 个项目</Run> <Run>(已选中 </Run> <Run Text="{Binding CurrentFileList,Converter={StaticResource CollectionSelectedCountConverter},Mode=OneWay}"></Run> <Run> 个项目)</Run> </TextBlock> </StackPanel> <TextBlock Text="该文件为空" Visibility="{Binding CurrentFileList.Count,Converter={StaticResource CountToVisibilityConverter}}" HorizontalAlignment="Center" VerticalAlignment="Center"></TextBlock> </Grid> </ScrollViewer> </Grid> </UserControl>