源码下载:

The project is now maintained herehttp://fsc.codeplex.com/

Introduction

I was recently asked to add a 'File Tree Pane' into my editor (https://edi.codeplex.com/discussions/541888) and went looking for a good solution, because the component is really missing and it really bothers me too. The best solution I found, was written by Thomas Willwacher, as usual, here at CodeProject. I really like the concept that Thomas is using and reviewed the project in terms of integrating it in my editor, and while that is still too come, I found already some issues that would probably be difficult to fix in a project that is driven by an IoC (which I'd like to do next).

 

It is difficult to write this down correctly, so do not get me wrong here, I am really grateful that Thomas has posted his solution. Because I am not even sure whether I could have developed such a nice File Explorer concept to start with. But I saw architectural issues and I decided to get this done instead of putting it off. So, here is my take on this solution. I am posting it here in the hope that it is useful to others and that we might be able to develop this even further.

Background

The solution presented here is about a File Explorer control that can be used in a Tool Window. The user should be able to browse directories, list their files, filter on the listed files, and open files via double click, drag & drop and context menu. The Drag & Drop and Context menu part is not presented here since I do not think this would be hard to add. The solution presented here is just about the same test application that Thomas had posted in his article. I only added a directory browser control and developed the architecture from scratch with MVVM in mind.

Using the code

The current articles discusses the code in FileListView_Version2.zip in the download section. The FileListView_Version2.1.zip in the download section is a refactored version that is currently under development based on my observations and Leung Yat Chun's suggestions in the forum's section.

Re-using the code of the provided solution requires that you reference the Dll assemblies (FileListView and FolderBrowser), and copy & parts of the MainWindow.xaml code into your own view implementation. You will also need the code MainWindow.xaml.cs to create the necessary viewmodels. This is about all you need to re-use this solution in your own projects.

Points of Interest

The solution presented here contains 4 projects:

  • FileListView, FileListViewTest and
  • FolderBrowser, TestFolderBrowser.

The FileListView project is the assembly that contains the meat of the File Explorer controls that this article is focusing on. The FolderBrowser project originates from a different CodeProject article [2] and was included here since I felt that I did not need a Recent Files selection but a Recent Locations selection. So, re-factored this solution, as well, and included the result here.

The 'Test' projects in this solution contain a demo application that can be executed to check out how things work. The remainder of this article will focus on the FileListView project but feel free to ask questions/demand more information if you feel that I should document the FolderBrowser part in more detail.

The Views in the FileListView Project

The FileListView project is mainly partitioned in 3 views that are completely separated from each other.

FilterComboBox

The FilterComboBox inherits from the ComboBox control [3] and should be fully theme-able since I'd like to support bright and dark skins. This is basically the control where you enter such filter as: '*.png', '*.*', or (I extended this) '*.png|*.jpg|*.jpeg'. This filter is then applied to the list of files when the user selects the filter or presses the enter key in the text portion of the combobox.

 Collapse | Copy Code
<fview:FilterComboBox DataContext="{Binding FolderView.Filters}"
ItemsSource="{Binding CurrentItems}"
SelectedItem="{Binding SelectedItem, UpdateSourceTrigger=PropertyChanged}"
Text="{Binding CurrentFilter, UpdateSourceTrigger=PropertyChanged}" fvbehav:SelectionChangedCommand.ChangedCommand="{Binding SelectionChanged}"
VerticalAlignment="Top"
HorizontalAlignment="Stretch"
Grid.Column="3"
Margin="3"
/>

The above code shows how the FilterComboBox control is implemented in the MainWindow's Xaml. A noteworthy item is the SelectionChangedCommand behavior [4] which is basically a custom ComboBox behavior that binds itself to to the KeyUp and SelectionChanged event of the combobox. The behavior executes the bound SelectionChanged command in the FolderComboBoxViewModel when either event occurs. This in turn executes the SelectionChanged_Executed method which evaluates whether the currently entered path refers to a valid directory or not. The method raises the OnCurrentPathChanged event of theFolderChangedEventArgs type if the entered path was in fact in existence. This event is received by another viewmodel discussed further below.

FolderComboBox

The FolderComboBox control is the combobox that keeps the list of folders that a user can select as the base of his exploration. This includes the usual suspects, such as, Desktop, My Documents, and Drives but also contains a list of Recent Locations:

The FolderComboBox makes also use of the SelectionChanged behavior discussed above. It is very similar to the FilterComboBox except for 2 additions:

 Collapse | Copy Code
<Setter Property="ItemTemplate">
<Setter.Value>
<DataTemplate DataType="{x:Type vm:FSItemVM}">
<Grid ToolTip="{Binding FullPath}" ToolTipService.IsEnabled="{Binding ShowToolTip}">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="{Binding Indentation}"/>
<ColumnDefinition Width="20"/>
<ColumnDefinition Width="100"/>
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition />
</Grid.RowDefinitions>
<Image Grid.Row="0" Grid.Column="1" Source="{Binding Path=DisplayIcon}" Width="16" Height="16"/>
<TextBlock Grid.Row="0" Grid.Column="2" Text="{Binding DisplayName}" />
</Grid>
</DataTemplate>
</Setter.Value>
</Setter>

This ItemTemplate shows tha items display in the drop-down section of the ComboBox consist of an Image and a TextBlock. The ItemTemplate binds to instances of the ItemVM type which is part of theObservableCollection<FSItemVM> CurrentItems collection in the FolderComboBoxViewModel.

 Collapse | Copy Code
<Setter Property="ItemContainerStyle">
<Setter.Value>
<Style TargetType="{x:Type ComboBoxItem}" BasedOn="{StaticResource {x:Type ComboBoxItem}}">
<Style.Triggers>
<DataTrigger Binding="{Binding}" Value="{x:Null}">
<Setter Property="IsEnabled" Value="False" />
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type ComboBoxItem}">
<Separator Width="0" Height="10"/>
</ControlTemplate>
</Setter.Value>
</Setter>
</DataTrigger>
</Style.Triggers>
</Style>
</Setter.Value>
</Setter>

The 2nd interesting thing in the FolderComboBox control is the ItemContainerStyle which includes aDataTrigger that inserts a Seperator when the bound value is null. The above Xaml literally converts a value of null into a seperator entry in the drop down list. This little trick inserts a Seperator in the drop-down list that allows us to group items such that users cannot click into the extra space (since seperators are not hit test visible).

FListView

The FListView is basically an out of the box ListView with an attached behavior addition that converts a double click into a bound DoubleClickCommand in the FileListViewViewModel [5].

The ViewModels in the FileListView Project

This solution includes a few more viewmodels than the original version 1. There is basically 1 viewmodel for each of the three controls documented in the previous section. The FolderComboBoxViewModel and the FileListViewModel make use of the FSItemVM class to manage their file specific collections. TheFolderListViewModel is the heart of the solution since it instantiates the other control specific viewmodels and manages their events when they say, hey:

  • ...just selected a new Folder
    (OnCurrentPathChanged in FolderComboBoxViewModel and FileListViewModel)
  • ...just selected a new Filter (OnFilterChanged in FilterComboBoxViewModel)
  • ...just want to open a file (OnFileOpen in FileListViewModel)

Conclusions

Converting this project took me about 3-4 days of work but I think it was worth it since I have a much clearer understanding now and feel motivated to add other toys such as an async query and load of the FileListView. This could include a stop button shown in the Folder or Filter combobox to stop process that may take extra ordinary long when accessing slow devices.

Over all I have learned a few more tricks looking deep into someone else's code, so I am once again grateful for being part of this community. And now I am looking forward to see what the community thinks about this.

Credits

The Class diagrams in this article were drawn with #Develop (http://www.icsharpcode.net/opensource/sd/).  I would like to say thank you for the original article and code version and the tips from Leung Yat Chun here at code project.

References

    • [1] A WPF File ListView and ComboBox (Version I) by Thomas Willwacher
      http://www.codeproject.com/Articles/167873/A-WPF-File-ListView-and-ComboBox
    • [2] WPF Folder Browser by Erik Rude
      http://www.codeproject.com/Articles/352874/WPF-Folder-Browser
    • [3] Inheriting from a Look Less WPF Control
      http://www.codeproject.com/Articles/575645/Inheriting-from-a-Look-Less-WPF-Control
    • [4] Patterns in Attached Behaviors
      http://www.codeproject.com/Articles/422537/Patterns-in-Attached-Behaviours
    • [5] AttachedCommandBehavior V2 aka ACB
      http://marlongrech.wordpress.com/2008/12/13/attachedcommandbehavior-v2-aka-acb/

A WPF File ListView and ComboBox的更多相关文章

  1. WPF中DataGrid的ComboBox的简单绑定方式(绝对简单)

    在写次文前先不得不说下网上的其他wpf的DataGrid绑定ComboBox的方式,看了之后真是让人欲仙欲死. 首先告诉你一大堆的模型,一大堆的控件模板,其实或许你紧紧只想知道怎么让combobox怎 ...

  2. [WPF 如何] 如何向 ComboBox 添加一个空白选项

    原文:[WPF 如何] 如何向 ComboBox 添加一个空白选项 看到这个问题,你可能会蔑视一笑 : 这也能成文章? 确实,你只需要在 ItemsSource 的0位置上插入一个空白的项就是了,如: ...

  3. WPF,ListView设置分组

    原文:WPF,ListView设置分组 今天遇到一个问题,就是在ListView中设置分组.想了很久在网上早了些资料作出一个例子. 分组字段也可以在后台中定义: CollectionView view ...

  4. 深入探讨WPF的ListView控件

    接上一篇博客初步探讨WPF的ListView控件(涉及模板.查找子控件)  我们继续探讨ListView的用法      一.实现排序功能 需求是这样的:假如我们把学生的分数放入ListView,当我 ...

  5. (转)利用WPF的ListView进行大数据量异步加载

    原文:http://www.cnblogs.com/scy251147/archive/2012/01/08/2305319.html 由于之前利用Winform的ListView进行大数据量加载的时 ...

  6. WPF之ListView使用WrapPanel

    原文:WPF之ListView使用WrapPanel 版权声明:本文为博主原创文章,未经博主允许不得转载. https://blog.csdn.net/jiuzaizuotian2014/articl ...

  7. 【C#/WPF】ListView的MVVM例子,及禁止拖动ListView的头部Header

    一个ListView的MVVM简单例子: <ListView ItemsSource="{Binding GoodsList}" Margin="0,10,0,10 ...

  8. WPF dataGrid下的ComboBox的绑定

    WPF dataGrid下的ComboBox的绑定 Wpf中dataGrid中的某列是comboBox解决这个问题费了不少时间,不废话了直接上代码 xaml 代码 <DataGridTempla ...

  9. 利用WPF的ListView进行大数据量异步加载

    原文:利用WPF的ListView进行大数据量异步加载 由于之前利用Winform的ListView进行大数据量加载的时候,诟病良多,所以今天试着用WPF的ListView来做了一下,结果没有让我失望 ...

随机推荐

  1. C++学习笔记10-面向对象

    1.  面向对象的程序设计是基于三个基本概念:数据抽象.继承和动态绑定. 在C++ 在,凭借一流的数据抽象,随着一类从一个类派生还继承:派生类的成员继承基类.决定是使用基类中定义的函数还是派生类中定义 ...

  2. POJ 1325 ZOJ 1364 最小覆盖点集

    题意:有A,B两台机器, 机器A 有 n个模式(0, 1, 2....n-1),同样机器B有m个模式, 两个机器一开始的模式都为0,有k个作业(id,x,y) 表示作业编号id, 该作业必须在A机器在 ...

  3. 日志收集之kafka

    日志收集之kafka http://www.jianshu.com/p/f78b773ddde5 一.介绍 Kafka是一种分布式的,基于发布/订阅的消息系统.主要设计目标如下: 以时间复杂度为O(1 ...

  4. aix 下 实现goldengate 随os启动而自己主动启动的脚本

    aix 下 实现goldengate 随os启动而自己主动启动的脚本: 1.用oracle用户建立/u01/info.txt,文件内容例如以下: sh date start mgr 2.chmod + ...

  5. 2014/08/23——OJ出现waiting...

    问题: 今天中午,裴主解决OJ他缓慢的问题后,开着.我跟着oj他递给发现了一个话题waiting该..... 和全哥.均觉得測评程序挂了.于是重新启动測系统,还waiting.....(測评系统的进程 ...

  6. 项目实践中--Git服务器的搭建与使用指南(转)

    一.前言 Git是一款免费.开源的分布式版本控制系统,用以有效.高速的处理从很小到非常大的项目版本管理.在平时的项目开发中,我们会使用到Git来进行版本控制. Git的功能特性: 从一般开发者的角度来 ...

  7. Java调用IIS发布的WebService

    之前的一篇博客说了一个实例,就是用VS2005在IIS上发布WebService.今天我们来实现在Eclipse上用Java来调用昨天发布的WebService. 首先咋在浏览器中输入http://1 ...

  8. 啊上班我排名可人皮号i家狂喷

    http://pan.baidu.com/share/link?shareid=3011665141&uk=338692646&third=15                http ...

  9. [置顶] 生成学习算法、高斯判别分析、朴素贝叶斯、Laplace平滑——斯坦福ML公开课笔记5

    转载请注明:http://blog.csdn.net/xinzhangyanxiang/article/details/9285001 该系列笔记1-5pdf下载请猛击这里. 本篇博客为斯坦福ML公开 ...

  10. 以todomvc为例分析knockout、backbone和angularjs

    一.整体结构 项目github地址https://github.com/tastejs/todomvc/ 排除通用的css样式文件和引用的js库文件,仅看html和js 1.1 knockoutjs版 ...