Кроме множества узлов, соответствующих дискам и папкам, мы собираемся ввести корневой узел с именем "My Computer". Поэтому целесообразно договориться о способе индексирования изображений, используемых деревом. Он должен соответствовать логике метода, приведенного ниже. Добавьте этот метод в класс FileSystemControl.
int GetImageID(string type, string name)
{
return
type == "3" ? 2 : // LocalDiskDrive
type == "5" ? 4 : // CDROMDrive
type == "2" ? name.StartsWith("A:") ? 8 : 6 : // RemovableDrive
type == "4" ? 10 : // NetworkDrive
type == "6" ? 12 : 0; // RAMDrive
}
Цель метода — выбор индекса изображения. Следующая таблица поясняет смысл его кода.
Индекс изображения |
Тип узла |
Состояние |
0 |
My Computer |
|
1 |
My Computer |
Selected |
2 |
LocalDisk |
|
3 |
LocalDisk |
Selected |
4 |
CDROM |
|
5 |
CDROM |
Selected |
6 |
Removable disk |
|
7 |
Removable disk |
Selected |
8 |
Removable disk(A:) |
|
9 |
Removable disk(A:) |
Selected |
10 |
Network disk |
|
11 |
Network disk |
Selected |
12 |
Ram Drive |
|
13 |
Ram Drive |
Selected |
14 |
Folder |
|
15 |
Folder |
Selected |
16 |
Folder (System, Hidden) |
|
17 |
Folder (System, Hidden) |
Selected |
Настало время подумать о дереве объектов файловой системы. В нем должен быть узел "My Computer", в который мы вложим все доступные диски (логические, съемные, сетевые). После этого в узлы, соответствующие дискам, мы вложим узлы, отображающие папки и т. д.
Алгоритмы управления большими деревьями (а наше, как раз такое) довольно сложны и требуют достаточно высокой культуры программирования. Если задаться целью один раз (при запуске программы) заполнить все дерево, то из этого ничего хорошего не выйдет. Сначала я написал рекурсивную функцию анализа и заполнения всего файлового дерева при начальном запуске приложения. Оказалось, что эта процедура занимает 5-7 минут, в течение которых приложение выглядит мертвым. Правда, после этого дерево раскрывает свои ветви мгновенно, потому что оно имеет информацию о всех своих ветвях. Если логических дисков и папок много (а в сетевой системе их очень много), то программа будет молчать очень долго. Кроме того, дерево потребует недопустимое количество памяти.
Обычно используют другие варианты работы с большими деревьями. Один из них состоит в том, что при проверке объекта файловой системы (диска или папки) он не сканируется далеко вглубь. Дерево обгоняет выбор пользователя лишь на один (или более) уровней вложенности узлов. Достаточно заполнить лишь один уровня (тот, который не виден пользователю). Если этого не сделать, то закрытый узел не будет иметь маркера раскрытия. Затем, когда пользователь действительно раскроет узел (это событие надо обработать), следует продвинуться вглубь дерева еще на один уровень вложенности. Раскрываемая же на данном шаге ветвь, уже наполнена реальными сущностями, так как это было выполнено на предыдущем шаге движения вглубь дерева.
Такой прием обеспечивает постепенное наполнение дерева по сценарию, определяемому пользователем. Вновь раскрываемые ветви вносят некоторую задержку, но после схлопывания (collapse) какой-либо ветви ее повторное раскрытие (expand) происходит быстро, так как информация уже записана в дереве (объекте tree класса TreeView). Альтернативным вариантом решения проблемы считается параллельное сканирование файлового дерева в отдельном потоке (thread) процесса приложения и постепенное заполнение его найденными узлами.
Уважаемый посетитель!
Чтобы распечатать файл, скачайте его (в формате Word).
Ссылка на скачивание - внизу страницы.