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.



21 comments:

  1. Hi Can we have the source code? Thank you!

    ReplyDelete
  2. Source code is already posted in the above code snippet . . .

    ReplyDelete
  3. how to get the path name treeview using wpf

    ReplyDelete
  4. This comment has been removed by the author.

    ReplyDelete
  5. ------ ---------------

    the binding keyword.. where does the text bind to in specific

    ReplyDelete
  6. TextBlock FontWeight="Heavy" Text="{Binding}"></TextBlock

    ReplyDelete
  7. Can u add check boxes to select parent then automaticaly child

    ReplyDelete
  8. what if we want to specify my own image icon for folder ?

    ReplyDelete
    Replies
    1. add the image file and change the code in ImageToHeaderConverter class

      Delete