|
Прошел курс. Получил код Dreamspark. Ввожу код на сайте, пишет: Срок действия этого кода проверки уже истек. Проверьте, правильно ли введен код. У вас осталось две попытки. Вы также можете выбрать другой способ проверки или предоставить соответствующие документы, подтверждающие ваш академический статус.
Как активировать код? |
Стандартные элементы управления
Спроектируем более совершенную версию программы для той же задачи построения дерева каталогов. Чтобы все было красиво, нужно извлечь иконки для соответствующих узлов из архива библиотеки VS2005ImageLibrary.zip, поставляемой в составе Visual Studio 2005.
Можно взять упомянутые иконки и из каталога Source данной работы.
Для включения значков в ресурс проекта, чтобы при компиляции они были внедрены в исполнимую сборку exe, нужно сделать следующее:
- В панели Solution Explorer на корневом узле проекта вызвать контекстное меню и командой Add/New Folder добавить в проект каталог Resource (или с любым другим именем)
- В панели Solution Explorer на добавленной папке вызвать контекстное меню и командой Add/Add Existing Item добавить в нее следующие файлы иконок
- 35FLOPPY.ICO
- CDDRIVE.ICO
- CLSDFOLD.ICO
- DRIVENET.ICO
- OPENFOLD.ICO
- В панели Solution Explorer выделить добавленные иконки и через панель Properties установить для них свойство Build Action в значение Embedded Resource (внедренный ресурс). Теперь иконки будут храниться в exe -файле, который можно перемещать без них куда угодно
Можно таким же образом внедрить в сборку иконку самой формы приложения (например, " 1.ICO " в каталоге Source )
Окончательный код усовершенствованной программы просмотра дерева каталогов будет таким
using System;
using System.Drawing;
using System.Windows.Forms;
// Пространство имен для работы с каталогами
using System.IO;
namespace Test
{
// Пользовательский класс построения дерева каталогов
// как расширение библиотечного класса TreeView
class DirectoryTreeView : TreeView
{
public DirectoryTreeView() // Конструктор
{
// Создаем список иконок из внедренного ресурса
ImageList imageList = new ImageList();
// Порядок соблюдать - от него зависят индексы списка
imageList.Images.Add(new Icon(GetType(),
"Resource.CLSDFOLD.ICO")); //0 - свернут
imageList.Images.Add(new Icon(GetType(),
"Resource.OPENFOLD.ICO")); //1 - развернут
imageList.Images.Add(new Icon(GetType(),
"Resource.35FLOPPY.ICO")); //2 - гибкий диск
imageList.Images.Add(new Icon(GetType(),
"Resource.CDDRIVE.ICO")); //3 - жесткий диск
imageList.Images.Add(new Icon(GetType(),
"Resource.DRIVENET.ICO")); //4 - папки
// Используем наследуемые от TreeView свойства
// Присоединяем список к свойству ImageList элемента TreeView
this.ImageList = imageList;
// В дереве в каждый момент времени может быть выделен только один узел
this.ImageIndex = 0; // Когда узел просто отображен (Collapsed)
this.SelectedImageIndex = 1;// Когда узел выделен (Open)
// Сканируем логические диски компьютера
DriveInfo[] drives = DriveInfo.GetDrives(); // Статический метод
// Строим дерево просмотра логических дисков и каталогов
TreeNode selectedNode = null;
foreach (DriveInfo drive in drives)
{
// Создаем очередной корневой узел для диска
TreeNode nodeDrive = new TreeNode(drive.RootDirectory.Name);
if (drive.RootDirectory.Name == @"C:\")
selectedNode = nodeDrive;
// Назначаем узлу пиктограмму в зависимости от типа диска
// Одинаковые изображения для свернутого и развернутого состояний
if (drive.DriveType == DriveType.Removable)
nodeDrive.ImageIndex = nodeDrive.SelectedImageIndex = 2;
else if (drive.DriveType == DriveType.CDRom)
nodeDrive.ImageIndex = nodeDrive.SelectedImageIndex = 3;
else
nodeDrive.ImageIndex = nodeDrive.SelectedImageIndex = 4;
// Добавляем узел диска в унаследованный TreeView
this.Nodes.Add(nodeDrive);
// Добавляем к корневому узлу подкаталоги ближайшего слоя
// с помощью нашей теперь уже нерекурсивной функции
AddDirectories(nodeDrive);
}
if (selectedNode != null)
this.SelectedNode = selectedNode;
}
// Нерекурсивная функция добавления узлов подкаталогов
void AddDirectories(TreeNode node)
{
node.Nodes.Clear(); // Очищаем коллекцию узлов на случай повторного
// раскрытия уже ранее раскрытого и сформированного узла
// Формируем полный путь для текущего каталога (узла)
DirectoryInfo dirInfo = new DirectoryInfo(node.FullPath);
// Объявляем ссылку на массив подкаталогов
DirectoryInfo[] arrayDirInfo;
// Если есть подкаталоги - безопасный код
try
{
arrayDirInfo = dirInfo.GetDirectories();
}
catch
{
// Подкаталогов нет - выходим
return;
}
// Добавляем к текущему узлу дочерний узел для каждого каталога
foreach (DirectoryInfo dir in arrayDirInfo)
node.Nodes.Add(new TreeNode(dir.Name));
}
// Переопределяем обработчик базового класса TreeView,
// который срабатывает перед раскрытием пользователем
// текущего узла, формируя ближайший слой дочерних узлов налету
protected override void OnBeforeExpand(TreeViewCancelEventArgs args)
{
base.OnBeforeExpand(args);
this.BeginUpdate(); // Замораживаем перерисовку дерева
// Быстренько создаем ближайший слой подузлов для каждого
// подузла раскрываемого узла, чтобы отображались
// значки + на узлах слоя после раскрытия текущего
foreach (TreeNode node in args.Node.Nodes)
AddDirectories(node);
this.EndUpdate(); // Освобождаем перерисовку дерева
}
}
// Класс приложения
class MyClass : Form
{
public MyClass() // Конструктор
{
this.Text = "Улучшенное дерево каталогов";
this.FormBorderStyle = FormBorderStyle.FixedSingle;
// Замыкаем размеры
this.MaximizeBox = false;
this.StartPosition = FormStartPosition.CenterScreen;
this.Width += this.Width / 3; // Чуток расширили форму
// Внедряем в сборку ресурс иконки формы
this.Icon = new Icon(GetType(), "Resource.1.ICO");
// Создаем экземпляр пользовательского класса дерева
DirectoryTreeView myTree = new DirectoryTreeView();
// Привязываем к форме
myTree.Parent = this;
// Разварачиваем на всю форму
myTree.Dock = DockStyle.Fill;
}
}
// Запуск
class Program
{
static void Main()
{
Application.EnableVisualStyles();
Application.Run(new MyClass());
}
}
}
Листинг
15.8 .
Усовершенствованная версия программы просмотра дерева каталогов
В старой программе с помощью рекурсивной функции, вызов которой был помещен в конструктор формы, мы вначале сканировали все дерево каталогов компьютера и тратили на это значительное время. Это существенно задерживало появление окна приложения при его запуске. В усовершенствованной программе в дереве просмотра для каждого раскрытого узла хранятся только два ближайших слоя дочерних узлов. При раскрытии пользователем очередного узла вначале срабатывает обработчик, которому передается коллекция дочерних узлов раскрываемого узла. В обработчике для каждого узла готовой раскрыться коллекции на лету создается новый слой дочерних узлов, готовых для раскрытия.
В новой программе мы всю работу разделили на этапы. Вначале создается два слоя - слой устройств и ближайший слой подчиненных им каталогов. При раскрытии узла устройства перед отображением уже вычисленного дочернего слоя вычисляется следующий в глубину слой для каждого дочернего узла, готовый для отображения при далнейшем раскрытии. Таким образом, при очередном шаге в глубину дерева вычисляется только один новый дочерний слой. Для пользователя эта задержка не очень заметна.
Вот внешний вид результата выполнения улучшенной версии программы чтения дерева каталогов

