{
tree.EndUpdate(); Cursor = Cursors.Default;
if (Текуший узел (узнайте его из параметра) — не корневой)
{
dirWatcher.Path = Из узла узнайте путь и вычлените из файлового пути логический диск
(используйте для этого метод класса Path) Все в одной строке кода!!
dirWatcher.EnableRaisingEvents = true;
}
}
Корневой узел (My Computer) следует обойти — он явно все портит. Итак, мы выставили сторожевую собаку по кличке dirWatcher из породы FileSystemWatcher. Мы приказали ей сторожить один из логических дисков. Какой? Собака залает, когда произойдут какие-либо изменения в этом (активизированном в нашем дереве) диске. При этом она (dirWatcher, конечно) вызовет одну из существующих, но пока не реализованных нами функций: dirWatcher_Changed или dirWatcher_Renamed. Пора за них браться.
В качестве упражнения укажите то место в программе, где собака получила наставление (делегата с заданием). Как создан делегат? Какой тип имеет его задание? Сколько действующих лиц (наблюдателей, или собак, делегатов, заданий) уже декларировано? Как изменить количество каждого?
private void dirWatcher_Changed (object sender, FileSystemEventArgs e)
{
string msg = "";
switch (в зависимости от типа изменений (узнайте из параметра))
{
case WatcherChangeTypes.Created: // Пока не знаем, что делать
break;
case WatcherChangeTypes.Deleted:
if (NodeExists (файловый путь узнайте его из параметра) // Если удаляемый узел существует
searchNode.Remove();
msg = "Directory deleted: ";
break;
}
UpdateStatusBar (Color.LightSkyBlue, msg + e.Name);
}
}
Логика реакции довольно прозрачна, но надо разработать функцию NodeExists. Очевидно, она должна возвращать true или false, в зависимости от того, есть ли узел с указанным путем в нашем дереве или нет. Вы помните, что дерево заполняется постепенно? Если удаляемый (кем-то и где-то) файл расположен в файловой системе глубоко, то в нашем дереве его может и не быть.
Итак, нам надо искать узел в дереве. Поиск в дереве — это излюбленная тема многих учебников по алгоритмам и структурам данных. Рекурсия здесь прямо напрашивается. Если вы сами напишите рекурсивную функцию, то получите большое удовольствие (это правда, я проверял). Рекурсивная функция сильно загружает стек, так как в нем хранятся все локальные переменные промежуточных вызовов. Параметры функции — это локальные переменные, поэтому рекурсивная функция должна иметь как можно меньше параметров.
Другой важный момент: при разработке рекурсивной процедуры следует задать ее глубину — барьер, при достижении которого рекурсия заканчивается. В нашем случае считайте, что барьером является найденный узел. Если ссылка searchNode (она уже есть в классе формы) не нулевая, то узел найден и пора возвращаться. Учитывая сказанное, напишем функцию NodeExists (она готовит рекурсию).
private bool NodeExists (string path)
{
searchPath = path.ToLower().TrimEnd('\\'); // Искомый путь. TrimEnd нужен при поиске корневых директорий
searchNode = null; // Устанавливаем барьер. (Пока узел не найден)
FindRecursive (root); // Эта функция должна искать узел (рекурсивно)
return searchNode != null; // Нашли или не нашли
}
Теперь создайте функцию рекурсивного поиска. Она должна вызывать чувство эстетического удовольствия.
private bool FindRecursive (TreeNode node) // true - либо нашли, либо нет смысла искать (так как целина)
{
foreach (Для каждого узла из коллекции узлов, вложенных в node)
{
string cur = Полный файловый путь текущего узла (узнайте из самого узла)
(но выкиньте из него"My Computer"/ Здесь понадобится rootLength
if (searchPath равна текущему cur) // Нашли
{
searchNode = Запоминаем текущий узел;
return true;
}
Уважаемый посетитель!
Чтобы распечатать файл, скачайте его (в формате Word).
Ссылка на скачивание - внизу страницы.