Windows Management Instrumentation. Опрос свойств, методов и описателей. Разработка компонента WMIControl, страница 34

void checkHidden_CheckedChanged(object sender, EventArgs e)

{

showHidden = checkHidden.Checked;

ToggleHidden();

}

public void ToggleHidden()

{

new FormMsg(Application.OpenForms[0], "Please, wait...", 1000);

Cursor = Cursors.WaitCursor;

tree.BeginUpdate();

foreach (TreeNode node in root.Nodes) // По всем узлам, вложенным в корневой узел дерева

{

expandedNodes.Clear();

GetExpanded(node);   // Заполнение коллекции раскрытых узлов

ClearTags(node);     // Очищаем все флаги заполненных узлов

node.Tag = null;

node.Nodes.Clear();

FillFolder(node, 1);

if (expandedNodes.Count > 0)

RestoreExpanded(node);  // Восстанавливаем коллекцию раскрытых узлов

}

tree.EndUpdate();

Cursor = Cursors.Default;

}

Метод ToggleHidden должен выполнить достаточно сложный маневр с деревом, отображающим файловую систему. Маневр заключается в том, чтобы:

¨  Заморозить перерисовку дерева и запомнить его текущее состояние,

¨  Уничтожить содержимое тех узлов, которые в данный момент раскрыты,

¨  Заново заполнить узлы дерева (только те, которые необходимо) с учетом необходимости показать или скрыть специальные папки,

¨  Восстановить состояние дерева, то есть раскрыть те узлы, которые были раскрыты до нажатия кнопки.

¨  Разрешить перерисовку дерева.

Возможно и другое решение (Тихановский А.С.): не уничтожать все узлы и не заполнять дерево заново, а аккуратно удалить или вставить только те узлы, которые необходимо.

Первый пункт перечня заданий достаточно прост. Рассмотрим алгоритм запоминания текущего состояния дерева. мы должны заполнить список expandedNodes (generic-коллекцию типа List<string>) тех узлов, которые вложены в данный и раскрыты в данный момент. Этот метод удобно сделать рекурсивным.

void GetExpanded(TreeNode node)

{

if (node.IsExpanded)

{

expandedNodes.Add(node.FullPath.Substring(rootName.Length + 1));

foreach (TreeNode n in node.Nodes)

GetExpanded(n);

}

}

Для того, чтобы те узлы дерева, которые помечены тэгами, как заполненные, обновились, надо очистить теги (свойства Tag) абсолютно всех узлов. Для этого мы вызываем функцию ClearTags. Вы догадываетесь, что она должна быть рекурсивной. Рассмотрим ее.

void ClearTags(TreeNode node)

{

foreach (TreeNode n in node.Nodes)

{

if (n.Tag != null)

{

n.Tag = null;

ClearTags(n);

}

}

}

Теперь необходимо разработать процедуру реставрации дерева. В течение этой процедуры вновь заполняются только те ветви, которые необходимы для того, чтобы показать дерево в том же состоянии, в каком оно было до поступления команды о перестройке.

При этом мы, конечно вызываем метод FillFolder, который учитывает изменившееся состояние флага ShowHidden. При повторном раскрытии дерева мы должны видеть системные и скрытые папки, которые ранее были не видны. Важно, чтобы этот процесс прошел плавно, без лишних перерисовок.

void RestoreExpanded(TreeNode node)

{

if (node.Nodes.Count == 0)

return;

if (expandedNodes.Contains(node.FullPath.Substring(rootName.Length + 1)))

{

foreach (TreeNode n in node.Nodes)

FillFolder(n, 2);

node.Tag = true;

node.Expand();

foreach (TreeNode n in node.Nodes)

RestoreExpanded(n);

}

}

При запуске приложения и нажатии кнопки checkHidden вы должны увидеть скрытые папки, например: System Volume Information, RECYCLER, Boot, inf, installer и другие. Мы сопоставили этим папкам специальные изображения, чтобы можно было отличить их по виду.

Реакция на подключение дисковых накопителей

В момент запуска приложения FileSystemControl определяет все логические диски, установленные в системе, но он не реагирует на подключение новых USB-устройств или вставку диска в CD/DVD ROM-устройство. Рассмотрим, как добавить эту функциональность в класс FileSystemControl.

¨  Вспомните, что в классе существуют объявления ссылок на объекты типа ManagementEventWatcher и пустая заготовка для метода SetEventWatchers. Добавьте код в метод SetEventWatchers.

void SetEventWatchers()

{

try

{

watchUSB = new ManagementEventWatcher("SELECT * FROM Win32_VolumeChangeEvent");