This article describe an obsoluted usercontrol which was released in 2009, it demonstrates how to construct FileExplorercontrols
included
<code>DirectoryTree and <code>FileList,
using
Model-View-ViewModel (MVVM) pattern, and is no longer being maintained. A newer version of the explorer control is described in this article here in codeproject.

Introduction

After C#
FileExplorer, VB.Net
ExplorerTree, you may think it's easier to write an explorer tree
in WPF. But in fact
it's not, and thats why this article takes so many pages.
Although
WPF is supposed to allow you
to construct custom interface with minium effort, WPF does
not even
provide the basic functionality of ListView
in .Net2.0 :

ViewMode? Small Icon? What is that?

Multi-Select? Sure! all you need is to press <shift> and
select each item.

Virtual ListView? ImageList? Rename? sure, write your own.

But anyone who run a WPF application
should know WPF let you to
customize everything, but you wont know these shortcoming until you are
going implement one. There are a number of solutions available on
various web
sites, I combined these ideas
as well as my code
and present you my finhsied FileExplorer
controls.

Further more, as these controls are written in Model-View-ViewModel
(MVVM)
pattern,
so
this article is also a brief tutorial for how to create the controls
using the pattern.

DirectoryTree (TreeView)

DirectoryTree

RootDirectory

SelectedDirectory

You can set the RootDirectory and
SelectedDirectory using the ExExtension.
Ex
is
a
MarkupExtension, which return the
appropriate FileSystemInfoEx,
one can specify the FullName via
the
extension
as
well
e.g.
:

FileList (ListView)

FileList

SelectedEntries

CurrentDirectory

ViewMode

ViewSize

SortBy (0.2)

SortDirection (0.2)

Unlike normal ListView, this FileList support
multi-select
by
dragging,
for
more
information
you
can take a look to this
article.
You can get the highlight
count when the FileList is
dragging,
using
the
an attached
property named SelectionHelper.HighlightCount,
e.g.
:
(Statusbar not
included in this publish)

If one set the ViewSize to
any value between 13 to 120, the filelist will
apply the view automatically. Noted that TileView is not
implemented yet.

The Design

The UserControls are developed using Model-View-ViewModel
approach (MVVM), I first learned about this approach from Dan
Crevier's Blog, but now you can find a simplified
explanation
here. Using MVVM improve
the application responsivenss, as most work can be threaded (and able
to update back to UI).

My Implementation included the followings :

Model

Represent a DirectoryInfoEx object

ViewModel - 2 kinds

Model of a DirectoryTree / FileList

Model of a DirectoryTreeItem /

FileListItem

/ FileListCurrentDirectory (which
embedded a
Model)

View

The DirectoryTree / FileList itself,
no
code-behind
except
DependencyProperties and some EventHandlers

These UserControls uses Sacha Barber's
Cinch MVVM framework. I am not sure if it's the best framework I
can get, as I haven't tested many of them, but it reduce a lot of my
work load. My only complaints is that his article is lack of a central
index, every time I wish to lookup for a description for a class I have
to look through 5 articles.

Unlike most MVVM projects
these are UserControls instead
of
Windows, I have to write a
number of DependencyProperties to
interface
between
the
UserControls,
and because of this,
performance may suffer, but I found it simplier to divide a large
projects into smaller managable pieces.

Model

Cinch.ValidatingObjet

Cinch.EditableValidatingObjet

ExModel

FileModel

DirectoryModel

DriveModel (0.3)

FileSystemInfoEx properties rarely change. so actually

FileSystemInfoEx

itself can be a model, but to support rename
I added another layer : ExModel.

Cinch contains two classes for implementing Model, ValidatingObject
and
it's derived class named EditableValidatingObject,
the
difference
is
that
EditableValidatingObject
have
transaction
support,
using
BeginEdit()
/ CancelEdit() and EndEdit() methods. To support
this, your properties have to be implemented as DataWrapper
class.

Because the only one field is required to support rename, I implement
ExModel as
ValidatingObject instead of EditableValidatingObject.

ExModel (abstract)

ExModel contains a FileSystemInfoEx entry
(accessable
using EmbeddedEntry property).
It is an abstract class, use
FileModel and DirectoryModel and DriveModel(0.3)
which is
inherited from

As you see, it will revert back to original if the rename process
failed,
otherwise update the internal _name field and call NotifyPropertyChanged()
method
so
the
UI
is
notified
about the changes.

ViewModel

Cinch.ViewModelBase

ExViewModel

DirectoryViewModel

CurrentDirectoryViewModel (FileList)

HierarchyViewModel

DirectoryTreeViewItemViewModel (TreeViewItem)

FileListItemViewModel (ListViewItem)

RootModelBase

DirectoryTreeViewModel (DirectoryTree which is a
TreeView)

FileListViewModel (FileList which is a ListView)

All my ViewModels are
inherited
from Cinch.ViewModelBase.
ViewModelBase,
as
a ViewModel communicating
with View, contains some
Window life-cycle related commands and method (e.g.
CloseCommand and OnWindowClose() method), but as the
file explorer
components are not Window most
of
them
are
not
used.
Instead,
I shall develop my own set of commands, like RefreshCommand for
FileList. There are a number of
unimplemented commands that I can think of, like
Cut/CopyPaste/SelectAllCommand for
FileList, if you need them
immediately you may need to write them yourself. e.g.

ExViewModel (abstract)

ExViewModel are a base class for all List/TreeViewItem,
it
contains
a
FileModel or DirectoryModel in it, which can be
accessed by a readonly property
named EmbeddedModel.
Each ExViewModel is for
representing one FileInfoEx or
DirectoryInfoEx only, to
represent another FileSystemInfoEx entry
one
would
have
to
create another ExModel
and ExViewModel.
Similarly, DirectoryViewModel and
HierarchyViewModel have EmbeddedDirectoryModel. So, if one
want to access the contained Directory, one can use
EmbeddedDirectoryModel.EmbeddedDirectory
property.

RootModelBase (abstract)

RootModelBase is a base class
for DirectoryTreeViewModel and
FileListViewModel, which is
the ViewModel of the whole UserControl, it
contains an event named OnProgress,
which
is
listened
by
the
UserControl. When UserConstrol receive this event, it
will raise
again as DependencyEvent,
which will bubble up until asked to stop (args.Handled = true;).

Actually both ViewModel should
be
combined
if
FileListViewModel
not
inherited from RootModelBase,
and CurrentDirectoryViewModel is
not
inherited
from
ExViewModel,
but as they do, I have to leave them as two
separate class. One FileList can
have
one
FileListViewModel only,
but it may have multiple CurrentDirectoryViewModels
(when changing directory).

FileListViewModel
(RootModelBase)

RootModelBase

FileListViewModel

RefreshCommand (which calls
CurrentDirectoryModel.Refresh())

CurrentDirectory

CurrentDirectoryModel

IsLoading

SortBy (0.2)

SortDirection (0.2)

FileListViewModelis a middle
layer between CurrentDirectoryModel
(which changes regularly) and the FileList. In
FileListViewModel,
CurrentDirectory and CurrentDirectoryModel links to each
other, if you
change one of them it will change the another, the reason to have both
properties is that, CurrentDirectory
is for outside the FileList
(e.g.
from DirectoryTree, or user
code), CurrentDirectoryModel
is for
internal use as ViewModel.

discussed in CurrentDirectoryViewModel is
still
used,
it's
sorting
method
is overrided by my own implementation.

Most ViewModel has IsLoading property, which will be
later bound to UI, so when it's true, the UI shows loading animation.

CurrentDirectoryViewModel
(ExViewModel)

ExViewModel

DirectoryViewModel

CurrentDirectoryModel

RefreshCommand

ListFiles, ListDirectories

IsLoading

Filter

BgWorker (bgWorker_LoadSubEntries
and
bgWorker_FilterSubEntries)

FileCount, DirectoryCount

HasSubEntries

SubEntries, SubEntriesInternal

CurrentDirectoryViewModelresponsible
for
listing
the
contents
of
current directory, to do this, it contains a Cinch.BackgroundTaskManager
named bgWorker_LoadSubEntries,
BackgroundTaskManager
as it's name implies, it allows running a task in background,
using the
RunBackgroundTask() method,
the advantage of using this class is that
you can specify the task and how to update back to ViewModel in one
place.

The first section is TaskFunc
(Func<FileListViewItemViewModel>),
which
does
the
time-consuming
work, and the second section is
CompleteAction (Action<FileListViewItemViewModel>),
which
update the UI
(run in UI thread). Noted that only the first section is run in
background.

The fiest section return the result of getEntries()
methods, getEntries()
is
a
method
with
a linq command, the _cachedSubEntries
is
used again when Filter needed.

Basically the second section is to identify the difference of result
and the output
(SubEntriesInternal), and
changes the ObservableCollection.
Instead
of
replacing
the
ObservableCollection completely, this reduce
the overhead needed to destroy and create of ListViewItem in the UI
side, and most importantly, it allow the FileList to maintain the
selection as long as possible.

FileList support Filter, when
the property is changed,
bgWorker_FilterSubEntries will
be run in background, and change the
SubEntriesInternal when
completed, it's similar as
bgWorker_LoadSubEntries,
except it uses filterEntries()
method
(as below)

So why it's called SubEntriesInternal
instead of SubEntries?
It's
because there's another layer, SubEntries
is a CollectionViewSource,
which
can
group
or
sort
the
SubEntriesInternal
without
changing
it
(e.g.
if
I want to sort SubEntriesInternal
directly I will have to do a
lot of work, Deleting and Inserting, you cant call Array.Sort() method
on ObservableCollection), SubEntriesInternal is sorted
using it's IsDirectory
property, then it's FullName property.

Because it's CollectionViewSource,
when
Binding
ItemsSource,
one
have
to
bind
it's
SubEntries.View
property
insteading
of the SubEntries property
directly. (btw, you can still bind to SubEntries.Source
as well)

Lastly, there's a FileSystemWatcherEx, which refresh the
FileList when
there's a change :

FileListItemViewModel
(ExViewModel)

ExViewModel

FileListItemViewModel

ExpandCommand

IsSelected

ExpandCommand run the
selected item (via Process.Start()
method) or
change the
current directory (via _rootModel.CurrentDirectory)
depend
what
is
selected.
If the selected file is a link (*.lnk) it uses VBaccelerator's
ShellLink to find the linked item, then run the file or change
directory based on the linked item.

CommandProvider
is a FrameworkElement which
have
an
attached
property named DoubleClickCommand,
and
when
it's
set, CommandProvider will
hook to
the control's MouseLeftButtonDown event,
in
this
case,
the ListViewItem.
It
will invoke the command when it receive a double click (clickcount =
2) event.

Beside DoubleClickCommand, it
also included other commands like Click,
RightClick, EnterPress, Prev and TreeViewSelectionChanged as well.

IsSelected is binded with ListViewItem.IsSelected, it have no
use currently,
but it can be used by the FileListViewModel
to change the item's
selected state.
It's intended for allowing FileList to setting the selected items
externally (just like DirectoryTree).

DirectoryTree -
DirectoryTreeViewModel and
DirectoryTreeItemViewModel

TreeView can be interpreted
as multi-level ListView, that
means unlike
WindowsForms you cannot get a TreeViewItem
by using
listView1.Items[0].Items[1], you cannot use TreeView's
ItemsContainerGenerator to get the
ListViewItem either, because
each level has it's own
ItemsContainerGenerator, you
have to use ListViewItem.Parent's ItemsContainerGenerator..

HierarchyViewModel (ExViewModel)

Cinch.ViewModelBase

ExViewModel

HierarchyViewModel

IsExpanded

IsSelected

One of the basic functionality of the DirectoryTree
is to display the
selected directory properly, in WPF, it's easy to obtain the selected
value in TreeView, but changing it is another story. In earlier
version I uses DaWanderer's
method which navigate through the TreeViewItem layer by layer to
find the
required item, and change it's IsSelected property, but this hog the
UIThread, and this disallow
Virtualizing TreeView to be used, because
if the item is not shown, it's not created, and if it's not created, it
cannot be selected. This
method is used when I develop the control using MVP
(Model-View-Presenter) pattern.

Until one day I read Josh
Smith's
article mentioned how to support selection in MVVM, the
problem solved itself. Basically it's to have IsExpanded and
IsSelected in the ViewModel
(in my case, HierarchyViewModel),
and
bind
the
TreeViewItem's IsExpanded and IsSelected to it. The issue of MVP
pattern is the lack of another layer (ViewModel) i.e. I cannot add
IsExpanded/IsSelected to FileSystemInfoEx.

So if you change the IsExpanded/IsSelected field in the ViewModel, it
will affect the ListViewItem.

DirectoryTreeViewModel
(RootModelBase)

RootModelBase

DirectoryTreeViewModel

BgWorker_FindChild

RootDirectoryModelList

RootDirectory

SelectedDirectoryModel

SelectedDirectory

IsLoading

Similar to FileList, there
are linked property : SelectedDirectory
and
SelectedDirectoryModel
property, so changing one will change the
other as well. The another pair is RootDirectory and
RootDirectoryModelList, except it's
a List, because TreeView.Items property accept a
List only.
DirectoryTree also have a FileSystemWatcherEx to refresh
the tree when
needed.

One important feature is when SelectedDirectory
is set externally, it
will update the Selected Item in DirectoryTree,
this
is
done
in
background using the BgWorker_FindChild
(which is a Cinch.BackgroundTaskManager),
as
follows
:

DirectoryTreeItemViewModel.LookupChild() method return the lookup
DirectoryTreeItemViewModel, or
it's parent's model if it cannot be found (which is rare). It
will expand if it's not
already expanded, because the expand is not run in UIThread it wont
make your
application freeze.

The cancelCheck will
cancel the iteration if the SelectedDirectory
is changed again when the lookup is working, it's pointless to
continue because another BgWorker_FindChild
is already started.

DirectoryTreeItemViewModel
(HierarchyViewModel)

ExViewModel

HierarchyViewModel

DirectoryTreeItemViewModel

RefreshCommand

SubDirectories

HasSubDirectories

IsLoading

bgWorker_loadSub

DirectoryTreeItemViewModel contains
a
Cinch.BackgroundTaskManager
(bgWorker_loadSub), It's
similar to CurrentDirectoryViewModel
except it
loads subdirectory only instead of both subdirectory and files.

Like FileList, DirectoryTree also contains a FileSystemWatcherEx which
montior the Desktop directory and it's sub-folders (instead of creating
a watcher for each directory). When there's a
change, it will call RootDirectoryModelList[0]'s BroadcastChange()
method, which will iterate through all created folders.

View

Most of the View I created are inherited from UserControl, but not
FileList and DirectoryTree. The major
reason is that these class
exposed a lot of properties thats required by other class, if I inherit
from UserControl I will have to re-write many DependencyProperties. The
another
reason is that I have a DragDropHelper
which have to be plugged to
TreeView/ListView only.

Both FileList and DirectoryTree have some code-behind, as it's easier
to code that way. To make it easier to be edit by Expression, true MVVM
project shouldnt have any View, and MVVM components should be connected
via ViewModel instead of Dependency properties.

DragDropHelper work with DirectoryInfoEx related controls only, you can
enable the support by adding a few lines in xaml :

If you need a specific ControlTemplate, lets say ListView, just google
"ControlTemplate ListView" and you can find the
template from msdn.

Update AssemblyInfo.cs,
add
the
following
: (which make it load your generic.xaml, you
only have to do it once per Class Library)

[assembly: ThemeInfo(
ResourceDictionaryLocation.ExternalAssembly, //where theme specific resource dictionaries are located//(used if a resource is not found in the page, // or application resource dictionaries)
ResourceDictionaryLocation.SourceAssembly //where the generic resource dictionary is located//(used if a resource is not found in the page, // app, or any theme specific resource dictionaries)
)]

ContextMenu handling is done in
UserControl level, DirectoryInfoEx has a static class named
ContextMenuWrapper, which can
generate the shell context menu for specified entries, all you need is
to provide the entries (in FileSystemInfoEx)
and
the
coordinate
(in System.Drawing.Point):

ProgressEvent is ProgressRoutedEventArgs.ProgressEvent,
which
is
a
RoutedEvent, it is raised if RootModel.OnProgress event is
raised by the
ViewModel.

IsEditing is an attached property, when
rename is issued (from the
Shell Context Menu) in FileList, it will set IsEditing of the specified
ListViewItem to true. On
the another side, the
ListViewItem.IsEditing is
bound to it's enclosed EditBox.

The following sample is taken from DirectoryTree,
as
it
looks simplier :

EditBox is a replacement of TextBox + Label, which display the Label
when not IsEditing, and TextBox (EditBoxAdorner) when IsEditing, it's a
technique
learned from ATC
Avalon
Team, but the EditBox
used in this project is a rewrite one,
with the following changes :

No longer bound to ListView

Has two value instead of one,

DisplayValue (display on the label) and

ActualValue (for editing),

which is required because a FileSystemInfoEx item's label
and
name may be different.

The converter (amti) is ExModelToIconConverter
which, similar to FileNameToIconConverter,
is
a
IValueConverter
can
convert
ExModel/ExViewModel
to
ImageSource.

FileList (ListView)

FileList

SelectedEntries

CurrentDirectory

ViewMode

ViewSize

IsLoading

RefreshCommand

View

FileListLookupBoxAdorner

Most of the properties here are explained in the ViewModel, except
these are DependencyProperties,
those
are
bound
to the RootModel's
related
properties.

FileList can have different Views,
a
View
can define ListView's Orientation, ItemContainerStyle, ItemTemplate,
HorizontalContentAlignment and whatever Listview's properties in one
place, if you look at VirtualWrapPanelView.cs
you can find the following :

To support multiple Views,
It's
a
good
idea
to
construct View
instead of setting each
properties individually.

There are 7 ViewModes, so you may
think
there are 6 Views
in
FileList
(and
TileView
is
not
implemented implemented in 0.3), actually there are just
VirtualWrapPanelView
and GridView.
There are only 3 different Views
derived
from
VirtualWrapPanelView,
which
is
SmallIconView, ListView and
IconView. The following is IconView, which is used by 3
similar ViewModes (vmIcon, vmLargeIcon and vmExtraLargeIcon).

Once you completed the View,
changing
ViewMode
is
just
one
line of code:

this.View = (ViewBase)(this.TryFindResource(IconView));

When you use the FileList,
remember leave some space below the control
(not necessary to be empty), because thats where the
FileListLookupAdorner placed
in. FileListLookupAdorner
is used to filter listed element by name, remember
CurrentDirectoryViewModel has a
property named Filter which
use runs a Cinch.BackgroundTaskManager
to filter the data. FileListLookupAdorner
can be bring up by pressing any key in file list.

It's harder to make the control as adorner, as I have to write the code
in cs instead of xaml, the advantage is that

it's separate from your main control, so you can reuse it in
other controls you made,

as all the unrelated logic code, like close the adorner when user
press the x button, is placed on the FileListLookupAdorner.cs
instead of the FileList.cs.

the FileListLookupAdorner is
shown
on
the
AdornerLayer,
which usually is the topmost, and it wont interfere other parts of the
main control.

I originally wanted to bind them together, but not sure why it's not
working, so I monitor the
changes and update when the text of the adorner is changed.

DirectoryTree (TreeView)

LoadingAdorner is shown when RootModel's BgWorker_FindChild (see
DirectoryTreeViewModel) is
working (or IsLoading equals
to true).

The DataTemplate of DirectoryTree is HierarchicalDataTemplate, which is
a DataTemplate that allow
you to set the ItemsSource
(or subItems). The complete template can be found above in
"Common in DirectoryTree/FileList" section,

VirtualWrapPanel/VirtualStackPanel - As the name
mention
it's virtual version (generate on demand) of specified panel, noted
that they are fixed-size only.
If you are interested, Thiago de Arruda has
developed
a VirtualizingWrapPanel that
support variable size.

EditBox- a
replacement of TextBox + Label, which display the Label
when not IsEditing, and TextBox (EditBoxAdorner) when IsEditing, more
information here.

EditBoxAdorner -
the TextBox part of the EditBox

LoadingAdorner - a
circular animation that shows when DirectoryTree
is
finding child.

SelectionAdorner -
display a rectangle when user is dragging
on FileList.

Conclusion

I have described how did I constructed the FileList and DirectoryTree
using the MVVM pattern, compared with NO pattern or MVP pattern,
using MVVM pattern have these advantages
:

split the code to simplify the developing process, and

make your application less UIThread
hogging, which makes it more responsive.

accessing property from ViewModel
instead of the UIElement (e.g.
adding
new
Tab in TabControl, or lookup item in TreeView)

without ViewModel
is quite hard to thread the items loading, which will freeze your
UI,

allow you to UnitTest
the ViewModel. Presenters are defined in a way
which is tightly coupled with the View
:

publicclass FileListPresenter : PresenterBase<FileListView> { ... }

The photo above shows the other UserControls
that I developed using the similar method described above, These are
not included in this article.
If
you
just go through my torture
article you should be able to create the controls yourself.

Lets say I want to construct the Toolbar using MVVM, I would

Construct and Style a ToolbarBase that have nothing to do with
MVVM, that included ToolbarBase and ToolbarItem

Make sure it's working without MVVM, using a simple WPF
application

Construct the UserControl
(e.g. Toolbar), which
contains or inherited from ToolbarBase

Construct Models and ViewModels

Construct an abstract class named ToolbarItemModel

Which represent a ToolbarItem,
you
may
want to have a ToolbarSubItem
as well.

Construct a ToolbarViewModel
(RootModel or DataContext), which will host a
number of ToolbarItemModel
(in ObservableCollection),
and method to poll them in background.

Construct custom ToolbarViewModels
(e.g. ViewModeViewModel, to
change ViewMode, see the
right side)

Construct View

Construct HierarchyDataTemplate
for the ToolbarViewModel

Configure Style to bind the ToolbarItem
dependency properties to ToolbarItemModel

Added a wide range of Commands (in SimpleRoutedCommand format, 6 for FileList, 2 for DirectoryTree and 6 for both), can be accessed by - calling FileList/DirectoryTree.Commands (In separate class to reduce the complexity of main control).- most of those commands are bound with a RoutedUICommands, like ApplicationCommands.SelectAll. - shortcut keys (e.g. F2 for rename) See FileList/DirectoryTree/SharedCommands.cs for details.

Comments and Discussions

I tried to support bookmarks with the FileExplorer. I can see you have some preparations for implementation/using this (there is a commented out BookmarkExplorerViewModel).
Right now I am seeing no "simple" way to have bookmarks shown in the explorer (or somehow saved/managed).
Am I missing something? Or is this really some bigger work?!

For FileExplorer2 it requires some work, as all view models in FileExplorer2 is strongly typed (e.g. FI, DI, FSI), you have to create your entity and have bookmark implement there, and that's what I did (created COFE1) when I develop my zippware.

If you are using DirectoryInfoEx, try modify them so they (DirectoryInfoEx/FileInfoEx) are inheritable, and make a BookmarkDirectory/BookmarkLink inherited from them.

thanks for your answer. Right now I am using the FileExplorer2. Your reply confirms my guess that there is some work to do. I will try it with your hint with inheriting from DirectoryInfoEx/FileInfoEx.

Hi Leung Yat Chun,
What does "The GNU Lesser General Public License (LGPLv3)" mean? Does it mean that I need pay if I want to use all source code of FileExplorer?
If I want to use all project which you develop in my application which is for selling, should I get licence or pay for it? Or could I use it free without any problem?
If I need get licence, how to get? And where to pay?
And for library "Cinch.DLL", I check it is 3rd library, could I use it free or also need get licence or pay it?
Best regards,

FileExplorer is originally released under LGPLv3 license and then MIT license.

Both licenses are open source license approved by OSI[^], which means the source is available to you, for free, and it doesn't restrict you to use it in freeware or commercialware, but you have to give the same right to the user, for me, a link in about page of your software mentioning you use the component is sufficient.

The difference of LGPLv3 and MIT is that, if you modified the source code of FileExplorer, in LGPLv3, you have to distribute the modified source code, while in MIT, you don't have to.

FileExplorer1&2 uses Cinch framework, which is under Ms-PL license, not compatible with LGPLv3, but compatible with MIT license.FileExplorer3 uses Caliburn Micro framework, which is under MIT license.

I hope this solve your question, also please noted that a newer version of FileExplorer exists: WPF x FileExplorer3 x MVVM[^], this version is no longer maintained.

Hi Leung Yat Chun,
What do you mean that I need distribute the modified source code? Do you mean that I need send the modified code to web or somewhere if I change modified?

And what do you mean for "a link in about page of your software mentioning you use the component "? How do do this?

In fact, I want to include project QuickZip.IO.PIDL.UserControls, QuickZip.UserControls and PIDL which is inside FileExplorer1__for_W7_and_VS2010, and I also will do some change in these project to fix some problem or enhance it. And I also download project of Cinch from codeplex to change for use.

So if I want to change and use these projects, what should I do? I saw that some source file had already added link address like www.QuickZip.org

Before the update of license, when under LGPLv3, if you modified the source code, you have to put it somewhere (in your binary or on web), so your user can have access the modified source code.

But as FileExplorer is under MIT license now, this no longer a requirement, you can include the modified library in your project.

quoted from tldrlegal, simplified version of the license:LGPLv2 : You may copy, distribute and modify the software provided that modifications are described inside the modified files and licensed for free under LGPL-2.1. Derivatives or non-separate (statically-linked) works of the software must be licensed under LGPL, but separate, parent projects don't have to be.MIT : A short, permissive software license. Basically, you can do whatever you want as long as you include the original copyright and license.Ms-PL : You can do anything you want with the software and source as long as you retain copyright and license and do not include the original authors as contributors.

So under the new MIT license, if you made some changes to FileExplorer(1/2/3), and would like to share, please tell me your changes and I will verify and update the source code, but this is not mandatory.

But under any of the above licenses, you have to include the copyright and license with your package deliver to user. I think the easiest way to do so is to create an about page and have all referenced projects linked (which includes not only FileExplorer, but also Cinch and ExifLib and probably SharpZipLib).

The PIDL project is now named DirectoryInfoEx, if your project named PIDL, you may be using an older version. I fixed a memory leak not long ago. The latest build is net45 based however.

The latest version is another rewrite, using Caliburn Micro framrwork, v3 simplified the code, retain most functionality of v2, and added some customizable features, includes

1. Existing controls (e.g. Navigation, Breadcrumb, FileList, DirectoryTree, Toolbar, Statusbar), with a theme update.
2. BreadcrumbList is updated to BreadcrubTree[^]
3. Drag n Drop/MultiSelect (they are refactored into UIEventHub[^])
4. Generic model which allow you to define your own non-file implementation (this time you can use different implementation in the same Explorer, e.g. Desktop directory in DirectoryInfoEx and another directory in GoogleDrive)
5. Toolbar/ContextMenu commands is now customizable : e.g.

I am using the FileExplorer in an AvalonDock-DockableContent-Element (http://avalondock.codeplex.com[^]).
Almost everything is working fine, but I noticed that the Breadcrumb doesn't change the "mode" when clicking in the address-line (it does change when clicking on the little icon at the beginning of the line but not elsewhere on the line).
Maybe you have an idea!? Don't know where to look for the problem...

1. Dimming items while scrolling. Displaying a "temporary" icon and other simplifications are fine, but making text gray takes away my ability to read it. I have to slow down scrolling just to understand where I am.

2. Very slow expanding of large folders in a tree. Not sure if it is caused by animating or enumerating, but I'd prefer it to be much faster. Explorer can delay the expansion of a tree, but it lists subfolders only when they all are ready to be displayed.

3. Animations during resizing of the window. They are "fancy" and serve no practical function.

On the whole, there are many animations which slow down navigation considerably, compared to the standard Explorer (including Open File dialogs etc.). If it is possible, I'd like to disable them (or make them much faster, no more than 150-250ms).

Also, scrolling of the list view is very slow. My computer is quite fast, but it may take as much as 1 second to display the next "frame". What causes this?

The items are not dimming, those items are just created, the implementation is virtual file list, disable it in
QuickZip.UserControls.Explorer/Themes/UserControl2/View/Common.xaml, thats why you can notice some speed down when you scrolling the list view, items are destroyed and re-created. Noted that only newly created items are shown that way.

The slowlyness of expanding folders are Both on animating and enumerate, but mainly on enumerate side. The DirectoryInfoEx became a bottleneck because it gets the handle whenever a new DirectoryInfoEx is created, regardless it's property is accessed or not, because the code has a lot of WinAPI so I am not going to update it to improve speed, as I fear I may break something.

I believe listing subfolders should be done as soon as the parent folder is found, not until parent folder is completely loaded.

I cannot find the code for item re-arrange animation right now, I will do a followup when I found it, it should be in coding but not markup. Please comment the code in QuickZip.UserControls\Components\VirutalPanel\AnimatedVirtualizingPanel.cs for disabling the animation when resizing window.

The implementation is completely built on .Net so it's quite hard to have performance comparable with Explorer, which is built on Native WinAPI.

If it take 1 second to display next frame in Icon view, then it's likely there's icon that took very long time to load, or there may be a bug somewhere.

Edit(22/10/13) - For those who want to disable the animation when resizing, all you need to do is to open VirtualWrapPanelView.xaml (FileExplorer\src\FileExplorer2\app\QuickZip.UserControls\Components\ListViewBase\), in <uc:VirtualWrapPanel>, add Duration=0 in the tag.

Edit(26/10/13) - For those who want the control only, an updated version of ListViewEx is available.

Edit(29/10/13) - There's a memory leak in AnimatedVirtualizingPanel, to fix it, add the following to AnimatedVirtualizingPanel.cs

I'm glad I found your explorer and think the 2nd version is great especially with the generic implementation.
I found the place where I can modify the organize-commands. But still I am having problems to really let them do something. Means: all the buttons are deactivated (not binded). Because I am new to the MVVM-Pattern I am looking for the right place to "inject" my routines for the commands.

Could you give a simple example (maybe for the "New Folder" command or similar) that I understand how I can use the organize-menu for my purposes?

As you can see, PredefinedDirectoryCommandModel allow you to create folder in toolbar, where GenericCommandModel allow you to create a command.
Beside using the constructor demos below, GenericCommandModel also support RoutedUICommands, like the ApplicationCommands.Close, you will have to bind them elsewhere, e.g. (in MainWindow)

thank you for your answer! But I see you didn't get my question right.
I understood how define my own commands in the profile. My problem is to "redefine" or "register" the predefined commands in the Organize Command-Model.
You declare them generally but I would like to "implement" and "register" these commands for my control.
Right now I would remove your predefined organize-menu and define it in my profile. I don't think that's the right way because the organize menu is always the same. I only don't see how I can register my routines for that menu.

sorry for the delay... I was very busy.
Thank you for your answer. I am on the way with understanding the structure of your commands. It takes me some effort to get the whole thing but this depends on me

I made some progress now with defining and implementing a command-model in the specific profiles and not to define it globally. So I am able to control everything in the one place. Now it's the goal to connect it to your DirEx-tools.

I hope I am not getting too annoying, but I am struggeling with the commands again:

Everything that you write in your answer is clear. But now I am trying to use your defined RoutedUICommands: ExplorerCommands.xyz

I registered some keybindings to them (that's what I look for). Now I would like to define the Run and CanRun in the profile. But where do I add the commandbindings?
My application holds several instances of your explorer and I need to register it for only that one that holds the specific profile.

thanks for the insight! Looks like it will be totally new concepted (new structure, other references,...) I am very interested in where it will lead, looks promising!
Keep your work going and good luck!