DCSIMG
WPF Explorer View with TreeView - David Sackstein's Blog

WPF Explorer View with TreeView

In this post we will see how to use WPF’s TreeView with the WPF Tookit’s DataGrid to present an Explorer-like view of a file system folder. We will use databinding with the HierarchicalDataTemplate, a sprinkling of LINQ and as little code as possible.

You can download the source code here.

User Interface Layout

As in Explorer, we will present a window with two vertical panes. The left pane will show the directory structure as a tree; the right pane will show the files in the folder that is selected in the left pane.

The layout is very simple. It contains a Grid with three columns: the left and right panels and a GridSplitter in the middle. The left panel contains a TreeView (directoryView) to represent the directory structure, the right panel contains a DataGrid (fileView), from the WPF Toolkit, to represent the list of files in the selected directory.

Left Pane : Directory View

Here is the markup for the TreeView:

      <TreeView Grid.Column="0" Name="directoryView">

         <TreeView.Resources>

            <HierarchicalDataTemplate DataType="{x:Type local:DirectoryRecord}"

                                     ItemsSource="{Binding Directories}" >

               <TextBlock Text="{Binding Info.Name}"/>

            </HierarchicalDataTemplate>

         </TreeView.Resources>

      </TreeView>

As you can see I have used the HierarchicalDataTemplate to format the nodes of the TreeView. See also this post about HierarchicalDataTemplate. Each node binds to an instance of the DirectoryRecord, which is a wrapper of the DirectoryInfo class. The wrapper is required in order to expose the GetFiles and GetDirectories methods as properties.

Here it is:

    class DirectoryRecord

    {

        public DirectoryInfo Info { get; set; }

 

        public IEnumerable<FileInfo> Files

        {

            get

            {

                return Info.GetFiles();

            }

        }

        public IEnumerable<DirectoryRecord> Directories

        {

            get

            {

                return from di in Info.GetDirectories("*", SearchOption.AllDirectories)

                       select new DirectoryRecord { Info = di };

            }

        }

    }

Right Pane: File View

This is the markup for the DataGrid

      <wf:DataGrid Grid.Column="2"

          Name="fileView"

          ItemsSource="{Binding ElementName=directoryView,

                        Path=SelectedItem.Files}"></wf:DataGrid>

The databinding is interesting. I have bound the ItemsSources to the Files property of the DirectoryRecord that is selected in the directoryView.

The default value of AutoGenerateColumns is true, but I filter the columns with the following delegate which is attached to the AutoGeneratingColumn event of directoryView

        private void fileView_AutoGeneratingColumn(

            object sender, DataGridAutoGeneratingColumnEventArgs e)

        {

            List<string> requiredProperties = new List<string>

            {

                "Name", "Length", "LastWriteTime"

            };

            if (!requiredProperties.Contains(e.PropertyName))

                e.Cancel = true;

            else

            {

                e.Column.Header = e.Column.Header.ToString().MixedCaseToSpace();

            }

        }

Finally, I added some styling for the DataGrid as follows:

   <Window.Resources>

      <Style TargetType="{x:Type wf:DataGrid}">

         <Setter Property="Background" Value="White"></Setter>

         <Setter Property="GridLinesVisibility" Value="Vertical"></Setter>

         <Setter Property="RowHeaderWidth" Value="0"></Setter>

         <Setter Property="VerticalGridLinesBrush"

                Value="{Binding ElementName=splitter, Path=Background}"></Setter>

      </Style>

   </Window.Resources>

Putting It All Together

In the constructor of the Window we install events for Loaded and the AutoGeneratingColumn of the fileView.

        public Window1()

        {

            InitializeComponent();

 

            this.Loaded += Window_Loaded;

            fileView.AutoGeneratingColumn += fileView_AutoGeneratingColumn;

        }

 

The folder to be viewed in the window is currently hard coded. You can easily add a browse button to allow the user to select the folder to view.

In the Loaded event we create the root node and bind it to the directoryView.

        string folder = @"..\..\";

 

        void Window_Loaded(object sender, RoutedEventArgs e)

        {

            var root = new ObservableCollection<DirectoryRecord>{

                new DirectoryRecord {

                    Info = new DirectoryInfo(folder)

                }

            };

            directoryView.ItemsSource = root;

            Title = "Explorer View (" + Path.GetFullPath(folder) + ")";

        }

 

Da Da!

Explorer View with TreeView

Performance

I think you will agree that the we have achieved quite a lot with very little code.

However, if you try to use the application to view the contents of your entire c: drive, you will wait a long time until the TreeView is filled.

Does anyone have any simple ideas to improve the performance?

Published Wednesday, September 02, 2009 12:19 PM by David Sackstein

Comments

# WPF Explorer View with TreeView - David Sackstein&#39;s Blog &middot; WPFdc

Pingback from  WPF Explorer View with TreeView - David Sackstein&#39;s Blog &middot; WPFdc

# re: WPF Explorer View with TreeView

Sunday, December 06, 2009 12:54 AM by Aviad P.

You can improve the GUI responsiveness (not the overall performance) by using PriorityBinding.

# re: WPF Explorer View with TreeView

Wednesday, May 12, 2010 9:15 AM by Konstantin

Simple and affordable. Thanks

# Ford Falcon Toys Hobbies On Ebay, Falcon Hid Found Safe Balloon Boy - 413.rkwrh.com

Pingback from  Ford Falcon Toys Hobbies On Ebay, Falcon Hid Found Safe Balloon Boy - 413.rkwrh.com

# Sephia Used Amanti Kia Sportage, Amanti Discount Kia 2009 Toyota - 82.jeepsunlimted.com

Pingback from  Sephia Used Amanti Kia Sportage, Amanti Discount Kia 2009 Toyota - 82.jeepsunlimted.com

# 2000 - 1991 @ Ford E 250 Headlight Econoline Club Wagon Explorer Sport Trac, Ford E 550 Econoline Super Duty Part Explorer Sport Trac Crown Victoria - 301.eumreborn.com

Pingback from  2000 - 1991 @ Ford E 250 Headlight Econoline Club Wagon Explorer Sport Trac, Ford E 550 Econoline Super Duty Part Explorer Sport Trac Crown Victoria - 301.eumreborn.com

# 2002 - 1980 @ 97 Mitsubishi Diamante Pricing, Diamante Pt Stock - 468.computeronlinebingo.com

Pingback from  2002 - 1980 @ 97 Mitsubishi Diamante Pricing, Diamante Pt Stock - 468.computeronlinebingo.com

# re: WPF Explorer View with TreeView

Monday, July 19, 2010 11:13 AM by James

Hi David,

Thanks for the above - much appreciated!

You mention at the end "Does anyone have any simple ideas to improve the performance?"

I found that I improved the performance and accuracy of the treeview (using it for network drive) by simply changing the GetDirectories searchOption to just show the current level and load child directories as needed:

return from di in Info.GetDirectories("*", SearchOption.TopDirectoryOnly)

                      select new DirectoryRecord { Info = di };

Hope this helps

# re: WPF Explorer View with TreeView

Thursday, November 25, 2010 10:27 AM by LogicNP

Great code! See Shell MegaPack (www.ssware.com/megapack.htm) for more functionality like shell context-menus, dragdrop, renaming, etc

# re: WPF Explorer View with TreeView

Tuesday, January 18, 2011 4:38 PM by boy

how to get .jpg file from directory when i choose directory, it will show picture on image control

# re: WPF Explorer View with TreeView

Monday, July 25, 2011 7:01 AM by Nik

I get  "Access to the path 'C:\Documents and Settings\' is denied." all the time. I'm run program as Administrator. When I run another fileviewer no exception is comming. Any ideas how to fix it?

Leave a Comment

(required) 
(required) 
(optional)
(required) 

Enter the numbers above:
Powered by Community Server (Commercial Edition), by Telligent Systems