|
Прошел курс. Получил код Dreamspark. Ввожу код на сайте, пишет: Срок действия этого кода проверки уже истек. Проверьте, правильно ли введен код. У вас осталось две попытки. Вы также можете выбрать другой способ проверки или предоставить соответствующие документы, подтверждающие ваш академический статус.
Как активировать код? |
Опубликован: 25.03.2010 | Уровень: для всех | Доступ: свободно
Лекция 15:
Стандартные элементы управления
Совместная работа элементов TreeView и ListView в Проводнике файловой системы
При выполнении последнего примера видно, что войти в дочерний каталог можно, но вновь вернуться в родительский каталог нельзя. Чтобы сделать программу, совсем похожую на Проводник Windows, давайте объединим два последних примера, представленные классами DirectoryTreeView и DirectoryListView. Для порядка поместим коды классов в отдельных файлах проекта. Вот какая программа в итоге получилась.
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(); // Освобождаем перерисовку дерева
}
}
}
Листинг
15.10 .
Файл DirectoryTreeView.cs
using System;
using System.Drawing;
using System.Windows.Forms;
using System.IO;
using System.Diagnostics;// Для класса Process
namespace Test
{
// Расширение библиотечного класса ListView
// для отображения файлов текущего каталога
class DirectoryListView : ListView
{
public DirectoryListView() // Конструктор
{
// Добавляем столбцы к ListView с нужной атрибутикой
this.Columns.Add("Имя", 150, HorizontalAlignment.Left);
this.Columns.Add("Размер", 100, HorizontalAlignment.Right);
this.Columns.Add("Тип", 100, HorizontalAlignment.Left);
this.Columns.Add("Изменен", 150, HorizontalAlignment.Left);
// Заготавливаем две коллекции для значков файлов
this.SmallImageList = new ImageList();
this.LargeImageList = new ImageList();
this.SmallImageList.ImageSize = new Size(16, 16);// По умолчанию
this.LargeImageList.ImageSize = new Size(32, 32);
}
// Базовое поле для свойства
string strDirectory;
public string Directory // Свойство
{
// Аксессоры
get { return strDirectory; }
set
{
// Принимаем текущий каталог
strDirectory = value;
// Очищаем коллекции строк и значков
this.Items.Clear();
this.SmallImageList.Images.Clear();
this.LargeImageList.Images.Clear();
// Загружаем иконку каталога
Icon icon = new Icon(this.GetType(),
"Resource.Folder.ico");
this.SmallImageList.Images.Add(icon);// Индекс значка 0
this.LargeImageList.Images.Add(icon);// Индекс значка 0
// Создаем объект DirectoryInfo для текущего каталога
DirectoryInfo dirInfo = new DirectoryInfo(strDirectory);
// Формируем информацию о подкаталогах
foreach (DirectoryInfo dir in dirInfo.GetDirectories())
{
// Создаем объект строки таблицы и первую ячейку "Имя"
ListViewItem item = new ListViewItem(dir.Name);
// Позиционируем строку на добавленный значок
item.ImageIndex = 0;
item.Tag = "dir"; // Пометили
item.SubItems.Add("");// Вторая ячейка "Размер"
item.SubItems.Add("Папка");// Третья ячейка "Тип"
// Четвертая ячейка "Изменен"
item.SubItems.Add(dir.LastAccessTime.ToString());
Items.Add(item);// Добавили в коллекцию
}
int imageIndex = 1; // Счетчик индексов значков
// Формируем информацию о файлах
foreach (FileInfo file in dirInfo.GetFiles())
{
// Создаем объект строки таблицы и первую ячейку "Имя"
ListViewItem item = new ListViewItem(file.Name);
// Комбинируем полный путь к файлу
string path = Path.Combine(file.DirectoryName, file.Name);
// Получаем значек, ассоциированный с типом файла
icon = Icon.ExtractAssociatedIcon(path);
// Добавляем значек в коллекцию иконок элемента ListView
this.SmallImageList.Images.Add(icon);// Индекс значка imageIndex
this.LargeImageList.Images.Add(icon);// Индекс значка imageIndex
// Позиционируем строку на добавленный значок
item.ImageIndex = imageIndex++;
// Вторая ячейка "Размер" с форматом
string str = String.Format("{0},{1} КБ",
file.Length / 1000, file.Length % 1000);
item.SubItems.Add(str);
// Третья ячейка "Тип"
string extension = Path.GetExtension(path).ToUpper() ==
".EXE" ?
"Программа" : "Документ";
item.SubItems.Add(extension);
// Четвертая ячейка "Изменен"
item.SubItems.Add(file.LastWriteTime.ToString());
Items.Add(item);// Добавили в коллекцию
}
}
}
// Переопределяем обработчик класса Control нажатия кнопки мыши
protected override void OnMouseDown(MouseEventArgs e)
{
base.OnMouseDown(e);
// Циклически меняем свойство View на одно из 5 значений перечисления
// Для смены представления задействуем правую кнопку мыши
if (e.Button == MouseButtons.Right)
this.View = (View)(((int)this.View + 1) % 5);// Деление по модулю 5
}
// Переопределяем обработчик класса ListView активации его элемента
// с помощью двойного щелчка левой кнопки мыши или клавиши Enter
protected override void OnItemActivate(EventArgs e)
{
base.OnItemActivate(e);
if ((string)SelectedItems[0].Tag ==
"dir")// Используем введенную ранее метку
{
// При щелчке на папке входим в нее
this.Directory = Path.Combine(this.Directory, SelectedItems[0].Text);
}
else
{
// Иначе безопасно запускаем программу,
// ассоциированную с выделенным файлом или файлами
foreach (ListViewItem item in this.SelectedItems)
{
try
{
Process.Start(Path.Combine(this.Directory, item.Text));
}
catch { } // Ничего не делаем
}
}
}
}
}
Листинг
15.11 .
Файл DirectoryListView.cs
using System;
using System.Drawing;
using System.Windows.Forms;
namespace Test
{
// Класс приложения
class MyExplorer : Form
{
// Объявляем ссылки-поля
DirectoryTreeView tree;
DirectoryListView list;
public MyExplorer() // Конструктор
{
// Настраиваем форму
this.Text = "Наш элементарный Проводник";
this.StartPosition = FormStartPosition.CenterScreen;
this.Width *= 2; // Увеличили ширину формы
// Внедряем в сборку ресурс иконки формы
this.Icon = new Icon(GetType(), "Resource.1.ICO");
// Создаем экземпляр класса DirectoryTreeView
tree = new DirectoryTreeView();
// Привязываем к форме
tree.Parent = this;
// Приклеиваем слева
tree.Dock = DockStyle.Left;
// Регистрируем обработчик выделения узла
tree.AfterSelect += new TreeViewEventHandler(tree_AfterSelect);
// Создаем экземпляр класса DirectoryListView
list = new DirectoryListView();
// Привязываем к форме
list.Parent = this;
// Приклеиваем справа
list.Dock = DockStyle.Right;
// Устанавливаем начальный режим "Таблица"
list.View = View.Details;
// Предусматриваем поддержку изменения размеров формы
WidthControl();
this.Resize += new EventHandler(ElementaryExplorer_Resize);
}
// Делим форму между элементами
void WidthControl()
{
int width = this.ClientSize.Width;
tree.Width = width / 4;
list.Width = width - tree.Width;
}
// При щелчке на каталоге показываем содержимое в list
void tree_AfterSelect(object sender, TreeViewEventArgs e)
{
list.Directory = e.Node.FullPath;
}
void ElementaryExplorer_Resize(object sender, System.EventArgs e)
{
// Делим форму между элементами
WidthControl();
}
}
}
Листинг
15.12 .
Файл MyExplorer.cs
using System.Windows.Forms;
namespace Test
{
// Запуск
class Program
{
static void Main()
{
Application.EnableVisualStyles();
Application.Run(new MyExplorer());
}
}
}
Листинг
15.13 .
Файл Program.cs
Внешнее представление программы будет таким
Итак, мы видим, что спроектированный нами MyExplorer имеет такую же (ну, почти такую!) функциональность, что и стандартный Проводник Windows.
