MessageBox.Show (e.Message, "Error"); // Сообщаем о других исключениях
return;
}
//===== Создайте цикл прохода по коллекции вложенных папок и вложите в него следующие 2 строки кода
if (showHidden || ((uint)dir.Attributes & hidden) == 0)
// Создаем и вставляем новый узел в коллекцию узлов узла node (одна строка кода !!!)
}
Спрятанные и ситемные папки надо показывать только если опущен флаг showHidden, поэтому в цикле используется условие. Для выбора изображений папки используйте индексы 10, 11.
Если вы успешно разобрались в логике, заложенной в методах GetPath и AddItems, то при запуске приложения увидите картину, подобную той, что показана на рисунке. Диски должны иметь маркеры раскрытия (+), а папки — нет. Почему? Потому, что узлы дерева, соответствующие им, пока пусты (пусты коллекции вложенных узлов).
Для того, чтобы пойти дальше, надо реализовать реакцию на начальную стадию раскрытия узла — функцию tree_BeforeExpand. Заготовка этой функции уже существует (мы создали ее как обработчик события BeforeExpand). Алгоритм таков: перед тем, как узел раскроется, надо продвинуться на один шаг вперед в процессе заполнения дерева. Для этого мы создадим специальный метод AddSubItems.
private void tree_BeforeExpand (object sender, TreeViewCancelEventArgs e)
{
//===== Получите ссылку на раскрываемый узел. Она спрятана в параметре типа TreeViewCancelEventArgs
Cursor = Cursors.WaitCursor; tree.BeginUpdate(); // Тормозим перерисовку
if (узел раскрывается впервые (спросите Tag))
AddSubItems (node); //===== Эта функция показана ниже
}
private void AddSubItems (TreeNode node)
{
foreach ( Узла n из коллекции узлов, вложенных в node)
AddItems (n); // Выполняем действие, реализованнае ранее
// Корректируем флаг, сигнализирующий факт заполнения коллекции (Tag)
}
Закончить начатый процесс следует в реакции на событие AfterExpand, иначе дерево так и не сможет закончить процесс перерисовки (ведь мы его заморозили).
private void tree_AfterExpand(object sender, TreeViewEventArgs e)
{
tree.EndUpdate(); Cursor = Cursors.Default;
}
В настоящий момент дерево должно функционировать так, как и было задумано. Маркеры раскрытия должны присутствовать во всех непустых узлах. Непустыми считаются узлы, в которых вложеные другие узлы (диски в узле "My Computer", или папки в остальных узлах).
В данный момент можно выбрать два пути развития проекта: заполнить список файлов в правой части формы, или ввести реакции на события файловой системы. Мы выбераем второй путь. Вы помните, что в классе уже присутствуют два наблюдателя (объекта класса FileSystemWatcher). Так как дерево пока умеет отображать только папки, то задействуем наблюдателя за папками (dirWatcher).
Важными свойствами наблюдателя являются Path и EnableRaisingEvents. Первое — позволяет задать файловый путь к папке или диску, за содержимым которой должен наблюдать dirWatcher, второе — просто включает или выключает его. Оба этих свойства еще спят — не заданы (если вы идете моим путем).
Суровым ограничением наблюдателя является то, что он не может следить за всей файловой системой. Самой крупной единицей слежения, по-видимому, является логический диск. Если так, то этот диск не должен быть жестко фиксирован. Очевидно, он должен меняться по мере того, как пользователь осуществляет навигацию по дереву.
Теперь надо решить, в каком месте программы и как, следует установить свойство Path? Так как дерево заполняется постепенно, то бесполезно реагировать на изменения объектов, информация о которых в нем отсутствует. Из этого делаем вывод: свойство Path должно зависеть от действий пользователя и наиболее удобным местом для корректировки Path (на мой взгляд) является реакция на событие AfterExpand.
private void tree_AfterExpand (object sender, TreeViewEventArgs e)
Уважаемый посетитель!
Чтобы распечатать файл, скачайте его (в формате Word).
Ссылка на скачивание - внизу страницы.