Такой прием обеспечивает постепенное наполнение дерева по сценарию, определяемому пользователем. Вновь раскрываемые ветви вносят некоторую задержку, но после схлопывания (collapse) какой-либо ветви ее повторное раскрытие происходит быстро, так как информация уже записана в дереве (объекте tree класса TreeView). Альтернативным вариантом решения проблемы считается параллельное сканирование файлового дерева в отдельном потоке и постепенное заполнение его найденными узлами.
Кроме демонстрации дерева и списка файлов, мы собираемся наблюдать за файловой системой, реагировать на изменения в ней и эффективно отображать их в дереве. Мы также собираемся оповещать приложение Client об изменениях в состоянии дерева (а позже и других компонентов) с тем, чтобы оно смогло отобразить сообщения в строке состояния (info).
Учитывая сказанное, введем в класс ExplorerControl два новых компонента типа FileSystemWatcher. Один (с именем fileWatcher) будет следить за файлами, другой (с именем dirWatcher) — за папками. Видимо, можно обойтись и одним компонентом, но мне показалось это неудобным. Вы можете поступить по-другому.
Здесь следует сделать замечание. Компоненты можно вводить с помощью дизайнера (тогда код их инициализации спрятан внутрь InitializeComponents), а можно и вручную (тогда мы пишем код сами). Довольно часто я предпочитаю второй способ, так как дизайнер своими установками по умолчанию и длинными, нечитаемыми выражениями постоянно меня подводит. Вы можете выбрать другой путь, но мой долг предупредить, что дважды пытаясь добится результата с помощью дизайнера, я терпел неудачу. Дело в том, что FileSystemWatcher требует тонкой настройки свойства NotifyFilter. Дизайнер же создает очень неуклюжее логическое выражение, которое не работает. Я предпочитаю видеть все выражения.
Несмотря на замечание, приведу перечень действий, которые надо выполнить, если вы решите воспользоваться услугами дизайнера.
¨ Перейдите в режим дизайна и добавьте два новых компонента типа FileSystemWatcher с именами: fileWatcher и dirWatcher. Установите им следующие свойства:
¨ EnableRaisingEvents в положение False (для обоих компенентов), // События пока выключены
¨ Filter = "" — пустая строка (для обоих компенентов), // Означает, что мы следим за всеми типами папок
¨ NotifyFilter = DirectoryName (только для компенента dirWatcher), // Следим только за папками
¨ IncludeSubdirectories в True (только для компенента dirWatcher), // Следим за вложенными папками тоже
¨ NotifyFilter = FileName, Size, LastWrite, CreationTime (только для компенента fileWatcher),
Далее, вручную введите в класс ExplorerControl множество новых переменных, смысл которых пояснен комментариями.
private FileSystemWatcher fileWatcher, dirWatcher; // Вставьте эту строку, если идете моим путем
private TreeNode root, searchNode; // Корневой и искомый узлы
private SortedList expandedNodes; // Коллекция раскрытых узлов
private string searchPath, rootName; // Искомый файловый путь и имя корневого узла
private int rootLength; // Длина имени корневого узла
public delegate void StatusHandler (Color clr, string msg); // Делегатный тип события
public delegate void DirCreatedHandler (TreeNode node); // Делегатный тип события
public event StatusHandler UpdateStatus; // Возбуждаемое нами событие "Изменения состояния",
private ListViewItem curItem; // Текущий элемент списка
private FileListComparer listComparer; // Объект вспомогательного класса для сортировки
public static string dateSep = " "; // Разделитель даты и времени
public bool showHidden; // Флаг состояния "Показывать скрытые папки"
private enum DiskTypes: byte { Removable=2, LocalDisk=3, Network=4, CDROM=5 };
private const int Removable = 2, LocalDisk = 3, Network = 4, CDROM = 5;
Уважаемый посетитель!
Чтобы распечатать файл, скачайте его (в формате Word).
Ссылка на скачивание - внизу страницы.