Вызов метода FillFolder надо производить в реакции на начальную стадию раскрытия узла (событие BeforeExpand). Заготовка функции обработки этого события tree_BeforeExpand уже существует (мы создали ее ранее). Алгоритм таков: перед тем, как узел раскроется, надо продвинуться на один (или более) шагов вперед в процессе заполнения дерева. Именно это и делает метод FillFolder.
void tree_BeforeExpand(object sender, TreeViewCancelEventArgs e)
{
if (e.Node.Parent != null)
{
new FormMsg(Application.OpenForms[0], "Please, wait...", 1000);
FillFolder(e.Node, 2);
}
}
Параметр 2 при вызове FillFolder означает, что мы хотим заполнить 2 уровня вложенности дерева.
В данный момент дерево умеет отображать диски и папки, но список fileList пока не умеет отображать файлы. Итак, надо вычислить список файлов, расположенных в папке, которая выбрана (selected) в дереве. Это традиционно делается в обработчике события, возбуждаемого в момент выбора узла дерева.
¨ В Win32 API (и MFC) для этого используют уведомление типа =TVN_SELCHANGED (знак = перед именем сообщения имеет тайный смысл: Message Reflection).
¨ В .NET Framework используют событие AfterSelect. Сравнение показывает насколько реалии .NET ближе к нормальному человеческому языку.
Рассмотрим реакцию на событие AfterSelect (выбор узла в дереве tree). В ней мы должны кроме заполнения следующих уровней дерева заполнить и показать список файлов, расположенных в выбранной папке.
void tree_AfterSelect(object sender, TreeViewEventArgs e)
{
if (e.Node.Parent != null)
{
new FormMsg(Application.OpenForms[0], "Please, wait...", 1000);
FillFolder(e.Node, 2);
FillFileList(e.Node);
}
}
В методе FillFileList необходимо опросить объект класса DirectoryInfo, реализующего функциональность директории Windows, получить множество файлов (метод GetFiles) в этой папке, пройти по этому множеству и создать для каждого файла строку в списке ListView. Напомню, что мы работаем с объектом fileList типа ListView. Нам надо заполнить его строками, которые содержат информацию о файлах в выбранной папке.
void FillFileList(TreeNode node)
{
fileList.Items.Clear();
if (node.Parent != null)
{
lblDirInfo.Text = node.Text;
DirectoryInfo dir = Получите информацию о папке, соответствующей узлу node
if (Пака dir существует)
{
lblDirInfo.Text = dir.Name;
FileInfo[] files;
try { files = dir.GetFiles(); }
catch (Exception ex) { lblDirInfo.Text += separator + ex.Message; return; }
hiddenCount = 0;
List<ListViewItem> items = Создайте список
foreach (Для каждого файла (FileInfo) из массива files)
{
ListViewItem item = CreateFileListItem(file);
if (item != null)
items.Add(item);
}
fileList.Items.AddRange(items.ToArray());
lblDirInfo.Text += separator + files.Length + " files";
if (hiddenCount > 0)
lblDirInfo.Text += separator + "(" + hiddenCount + " hidden)";
}
}
}
Промежуточный список типа List<ListViewItem> (он размещен в памяти) ускоряет работу алгоритма, так как заполнение строк списка ListView (на форме) выполняется после цикла прохода по файлам однократным вызовом метода AddRange. Такой метод присутствует во многих типах коллекций библиотеки классов .Net Framework.
Рассмотрим вспомогательный метод CreateFileListItem, который определяет атрибуты файла (имя, размер, дату создания и дату изменения) и форматирует их, чтобы повысить читабельность данных. Если установлен флаг showHidden, то скрытые файлы также попадают в список файлов, но они выделяются цветом.
ListViewItem CreateFileListItem(FileInfo file)
{
bool bHidden = ((uint)file.Attributes & hidden) != 0;
if (bHidden)
hiddenCount++;
if (!bHidden || showHidden)
{
long len = file.Length;
string size =
len > 1073741823 ? (len / 1073741824.0).ToString("f2") + " G" :
len > 1048575 ? (len / 1048576.0).ToString("f2") + " M" :
len > 1024 ? (len / 1024.0).ToString("f2") + " K" : len.ToString();
Color clr = bHidden ? Color.FromArgb(150,150,255) : Color.Black;
Уважаемый посетитель!
Чтобы распечатать файл, скачайте его (в формате Word).
Ссылка на скачивание - внизу страницы.