Friday 23 August 2013

WPF - Create a Directory Viewer in Treeview



   In this article we are going to see how to create a Directory viewer in WPF using treeview and bind the images based on the type. For that first we have to iterate the directory to get the information of Directories and files present inside the directory. For binding the image to the treeviewitem based on file and directory create a custom converter.

  


WPF Code:


<Window x:Class="Directory_view.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:local="clr-namespace:Directory_view"
        Title="Directory Viewer" Height="550" Width="525" Loaded="Window_Loaded" Icon="folder.png">
    <Window.Resources>
        <local:ImageToHeaderConverter x:Key="img"/>
    </Window.Resources>
    <Grid>
        <TreeView Name="folders" MouseDoubleClick="folders_MouseDoubleClick">
            <TreeView.Resources>
                <Style TargetType="TreeViewItem">
                    <Setter Property="HeaderTemplate">
                        <Setter.Value>
                            <DataTemplate>
                            <StackPanel Orientation="Horizontal">
                                <Image Width="25" Height="15" Source="{Binding Path=Tag,RelativeSource={RelativeSource AncestorLevel=1,AncestorType=TreeViewItem,Mode=FindAncestor},Converter={StaticResource img}}"></Image>
                                <TextBlock FontWeight="Heavy" Text="{Binding}"></TextBlock>
                            </StackPanel>
                            </DataTemplate>
                        </Setter.Value>
                    </Setter>
                </Style>
            </TreeView.Resources>
        </TreeView>
    </Grid>
</Window>


 C# Code
public partial class MainWindow : Window
    {
        public MainWindow()
        {
            InitializeComponent();
        }

        private void Populate(string header, string tag,TreeView _root,TreeViewItem _child,bool isfile)
        {
            TreeViewItem _driitem = new TreeViewItem();
            _driitem.Tag = tag;
            _driitem.Header = header;
            _driitem.Expanded += new RoutedEventHandler(_driitem_Expanded);
            if(!isfile)
            _driitem.Items.Add(new TreeViewItem());
           
            if(_root!=null)
            { _root.Items.Add(_driitem); }
            else{_child.Items.Add(_driitem);}
        }

        private void Window_Loaded(object sender, RoutedEventArgs e)
        {
            foreach (DriveInfo driv in DriveInfo.GetDrives())
            {
                if(driv.IsReady)
                Populate(driv.VolumeLabel+"("+driv.Name+")", driv.Name, folders,null,false);
            }
        }

       
        void _driitem_Expanded(object sender, RoutedEventArgs e)
        {
            TreeViewItem _item = (TreeViewItem)sender;
            if (_item.Items.Count == 1 && ((TreeViewItem)_item.Items[0]).Header == null)
            {
                _item.Items.Clear();
                foreach (string dir in Directory.GetDirectories(_item.Tag.ToString()))
                {
                    DirectoryInfo _dirinfo = new DirectoryInfo(dir);
                    Populate(_dirinfo.Name, _dirinfo.FullName, null, _item,false);
                }

                foreach (string dir in Directory.GetFiles(_item.Tag.ToString()))
                {
                    FileInfo _dirinfo = new FileInfo(dir);
                    Populate(_dirinfo.Name, _dirinfo.FullName, null, _item,true);
                }

            }
        }

        private void folders_MouseDoubleClick(object sender, MouseButtonEventArgs e)
        {
            if (e.Source is TreeViewItem && ((TreeViewItem)e.Source).IsSelected)
            {
               
            }

        }


HeaderToImageConverter:

  This class will bind the Header  image based on the tag value. If the Drive is present, Drive image is bind. If Directory is present folder image will bind and for file also.

public  class ImageToHeaderConverter:IValueConverter
    {
        public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
        {
            string tag = (string)value;
            if (File.Exists(tag))
            {
                return "file1.png";
            }
            if (tag.Length > 3)
            {
                return "folder.png";
            }
            else
            {
                return "Hard drive.png";
            }
        }

        public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
        {
            throw new NotImplementedException();
        }
    }




From this article I hope you can have idea of TreeView control and how to display the data in TreeViewItem and also How to iterate the information of Directory and Drives.