Windows Management Instrumentation. События в WMI. Библиотека классов MyWMI. Особенности работы с большим деревом, страница 13

    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)