Страницы

9 июля 2013 г.

Пишем ленивый файловый обозреватель на C#

На собеседовании дали небольшое задание. Смысл заключался в написании маленького файлового обозревателя с обязательной ленивой подгрузкой информации о файлах и папках. Всё это должно быть написано на C# и использовать элемент TreeView (WPF).
Как всё должно работать? Создаём дерево, вешаем событие развёртывания узла, добавляем подгрузку информации на текущем каталоге. Далее по порядку.
Итак, первым делом заходим в конструктор, вытягиваем элемент TreeView  из панели инструментов, задаём имя treeView и параметр Loaded. Должна получиться вот такая строка, расположение элемента значения не имеет

<TreeView Name ="treeView" Loaded="TreeView_Loaded" />

Переходим к коду. Для работы с дисками нужно добавить строчку 

using System.IO;

Теперь создадим функцию создания дерева томов. Она должна иметь тип TreeViewItem и имя TreeView_CreateTree.  Далее добавляем корень к дереву с произвольным названием (My computer, например), заполняем узлами с именами дисков, устанавливаем состояние развёртывания.

 TreeViewItem TreeView_CreateTree()
 {
    TreeViewItem Mycomputer = new TreeViewItem { Header = "My computer", IsExpanded = false };
     foreach (var drive in DriveInfo.GetDrives())
      {
        TreeViewItem treeDrive = new TreeViewItem();
       try
       {
        treeDrive.Header = String.Format("{0} ({1}:)", drive.VolumeLabel, drive.Name[0]);
           treeDrive.Items.Add(null);
       }

       catch { }

        treeDrive.Tag = drive.Name;
        treeDrive.Expanded += TreeViewItem_Expanded;
        Mycomputer.Items.Add(treeDrive);
       }
        return Mycomputer;
   }
       
 
Для обеспечения ленивости добавим загрузку информации в событие развёртывания узла.
 void TreeViewItem_Expanded(object sender, RoutedEventArgs e)
  {
   TreeViewItem rootItem = (TreeViewItem)sender;
    if(rootItem.Items.Count == 1 && rootItem.Items[0] == null)
      {
       rootItem.Items.Clear();
  //массивы для последующего вывода  файлов и папок       
      string[] dirs;
       string[] files;
       dirs = Directory.GetDirectories((string)rootItem.Tag); //получаем все папки и файлы на текущем узле
       files = Directory.GetFiles((string)rootItem.Tag);
       foreach (var dir in dirs) //заполнение дерева папками
       {
        TreeViewItem subItem = new TreeViewItem();
        subItem.Header = new DirectoryInfo(dir).Name;
        subItem.Tag = dir;
        subItem.Items.Add(null);
        subItem.Expanded += TreeViewItem_Expanded;
        rootItem.Items.Add(subItem); 
       }

  foreach (var fils in files) //заполнение дерева файлами
    {               
     TreeViewItem subItem = new TreeViewItem();
      subItem.Header = new DirectoryInfo(fils).Name;
      subItem.Tag = fils;
    try
      {
        if (Directory.GetFiles(fils).Length > 0)
          subItem.Items.Add(null);
      }
      catch { }
    subItem.Expanded += TreeViewItem_Expanded;
    rootItem.Items.Add(subItem);
     }
 }

Теперь, чтоб это всё работало, добавим функцию, которая будет работать при загрузке элемента treeview и вызывать функцию заполнения узлов именами дисков

void TreeView_Loaded(object sender, RoutedEventArgs e)
{
 treeView.Items.Add(TreeView_CreateTree());
}
Собственно, готово. Компилируем, смотрим результат, радуемся :3

2 комментария: