
- •Урок 7. Работаем с xml-файлом
- •Урок 10. Класс SystemInformation
- •Урок 13. Получаем список всех установленных шрифтов
- •Урок 15. Продолжаем работать с TreeView
- •Урок 17. Применяем стили xp
- •Урок 18. TreeView - показываем каталоги
- •Урок 19. TreeView для каталогов - продолжение
- •Урок 26.Передаем данные из диалога
Урок 19. TreeView для каталогов - продолжение
Продолжаем заниматься нашим деревом каталогов.
Вот код обещанного на прошлом уроке метода NodeExpand:
// Раскрытие ветки дерева.
private void NodeExpand(TreeNode tn)
{
// Если есть подузлы.
if(tn.Nodes.Count!=0)
{
// Если раскрываем в первый раз.
if(((string)tn.Tag)=="")
{
// Удаляем фиктивный узел.
tn.Nodes.RemoveAt(0);
// Добавляем подузлы.
AddTreeNodes(tn);
// Устнавливаем признак того, что
// узел уже раскрывали и добавили в него все подузлы.
tn.Tag = "+";
}
}
}
Тут мы опять делаем только часть работы (чтобы не запутаться) - а именно вызываем пока не написанный нами метод AddTreeNodes. Наш код достаточно прост - а именно мы раскрываем наш узел только если он не пуст (проверка условия tn.Nodes.Count!=0). Если он не пуст, то мы удаляем добавляемый при создании фиктивный узел (который служил только для того, чтобы показать знак "+" для непустых папок у нашего дерева) и добавляем реальные подузлы (напомним еще раз, что для этого нам еще предстоит написать метод AddTreeNodes). Далее мы устанавливаем для нашего узла признак того, что он уже раскрывался и что нам для него не надо будет добавлять узлы (т. е. записываем в свойство Tag значение "+").
Давайте на этом уроке напишем еще один вспомогательный метод - GetFullPath. Этот метод по узлу нашего дерева возвращает полный путь (т. е. от корневого узла (папки), до нашего узла (папки), включая все промежуточные узлы (папки)). Вот код метода GetFullPath:
// Получение полного имени папки по узлу.
private String GetFullPath(TreeNode tn)
{
// Устанавливаем текуший узел на переданный в параметре.
TreeNode currNode = tn;
// В полное имя пока записываем текст,
// показываемый в текущем узле.
String fullPath = currNode.Text;
// Двигаемся к корню дерева.
while(currNode.Parent!=null)
{
// Переходим на родительский узел.
currNode = currNode.Parent;
// К полному имени приписываем текст родитеского узла.
fullPath= currNode.Text + @"\" + fullPath;
}
// Возвращаем полный путь.
return fullPath + @"\";
}
Принцип работы этого метода такой - берем родительский узел для нашего узла, приписываем его текст влева, потом берем родительский узел для родительского, берем узел для него и т. п., пока не окажемся в корневом узле (который соответствует диску в файловой системе).
Урок 20. TreeView для каталогов - окончание
Осталось для нашего дерева папок, начатаго на уроке 18, добавить метод AddTreeNodes для добавления подузлов. Вот его код (этот метод добавляем естественно, в класс формы):
// Добавление подузлов.
private void AddTreeNodes(TreeNode tn)
{
TreeNode aux;
// Получаем полный путь для папки узла.
DirectoryInfo d = new DirectoryInfo(GetFullPath(tn));
// Массив для хранения подпапок.
DirectoryInfo[] ds;
try
{
// Получаем все подпапки для папки.
ds = d.GetDirectories();
// Для каждой папки выводим ее имя и имена всех подпапок.
foreach (DirectoryInfo s in ds)
{
// Добавляем каждую подпапку.
aux = tn.Nodes.Add(s.Name);
// Устанавливаем для нее признак, что ее еще не раскрывали.
aux.Tag = "";
try
{
// Если она не пуста,
if(s.GetDirectories().GetLength(0)!=0)
{
// то добавляем в нее фиктивный узел.
aux.Nodes.Add("");
}
}
// Перехватываем исключение запрещенного доступа.
catch (UnauthorizedAccessException)
{
};
}
}
//Перехват общего исключения (например, если диск a: не вставлен).
catch(Exception)
{
}
}
Тут есть несколько тонкостей. Во-первых, мы используем исключения. Это необходимо потому, что не все диски или папки могут оказаться доступными. Во-вторых, обратите внимание, что плюсики мы добавляем не к каждому узлу, а только к непустым. Т. е. рядом с пустыми папками сразу ничего показываться не будет.
Все. Можно запускать программу. Будет она выглядеть приблизительно так:
Обратите внимание, что знак плюсика есть не у каждой папки - а именно у пустых папок его нет.
Урок 21. Как создать экземпляр класса по его имени?
Часто требуется создать экземпляр некоторого класса по его имени. Например, для конфигурации некоторой программы - имя нужного класса может хранится в конфигурационном файле. Или же имя может задать пользователь в каком-нибудь диалоговом окне приложения.
В приведенном ниже примере для Windows мы сделаем это через метод CreateInstance класса Activator. Для этого примера нам понадобятся один интерфейс ISomeInterface и два производных от него класса Class1 и Class2. В принципе можно обойтись и без них, но с ними легче показать, что экземпляры наших классов Class1 и Class2 действительно создаются. Вот объявление интерфейса:
namespace WindowsApplication1
{
public interface ISomeInterface
{
void SomeMethod();
}
}
Как вы видите, мы тут ввели некоторый метод SomeMethod.
А вот объявление двух классов:
namespace WindowsApplication1
{
public class Class1 : ISomeInterface
{
public void SomeMethod()
{
System.Windows.Forms.MessageBox.Show("Class1");
}
}
}
и
namespace WindowsApplication1
{
public class Class2 : ISomeInterface
{
public void SomeMethod()
{
System.Windows.Forms.MessageBox.Show("Class2");
}
}
}
Как вы видите, оба эти класса являются потомками объявленного ранее интерфейса. Реализация метода SomeMethod у них очень похожа - каждый класс показывает своем имя в messagebox'е.
Теперь код, непосредственно создающий экземпляр класса по имени. Добавьте на форму кнопку и текстовое поле. В обработчике для кнопки напишите такой код (он и есть самый важный в нашем приложении):
private void button4_Click(object sender, System.EventArgs e)
{
// Получаем тип по имени.
Type t = Type.GetType("WindowsApplication1."+textBox1.Text);
// Создаем переменную по типу.
ISomeInterface w = (WindowsApplication1.ISomeInterface)
Activator.CreateInstance(t);
// Вызываем метод.
w.SomeMethod();
}
Запускаем программу. При вводе в текстовое поле имени соответствующего класса и нажатии на кнопку создастся его экземпляр - это мы увидим по соотвествующему messagebox'у:
Урок 22. Использование гиперссылки (LinkLabel)
Элемент гиперссылка (LinkLabel) выглядит на панели Toolbox как синяя подчеркнутая буква A:
Перетащите его на форму нашего приложения. Рассмотрим для начала основные свойства. Разумеется, это LinkColor (цвет непосещенной ссылки), VisitedLinkColor (цвет посещенной ссылки), Text (надпись, которая непосредственно видна на гиперссылке), Cursor (можно сразу установить в Hand (курсор в виде перста указующего)), LinkVisited (свойство булевского типа, если оно установленов true, то для гиперссылки используется VisitedLinkColor цвет, если в false, то LinkColor).
Тепрь посмотрим, что нам надо сделать, чтобы при щелчке на нашей гиперссылке запускался браузер по умолчанию и в нем открывалась некоторая заданная нами web-страничка.
Во-первых, мы должны где-то адрес нашей web-страницы хранить. Вот как, например, это можно сделать:
...
linkLabel1.Links[0].LinkData = "http://progs.biz";
...
Как вы видите, существует целая коллекция Links, так что в принципе мы можем хранить несколько ссылок.
И, во-вторых, мы должны добавить обработчик щелчка мыши по нашей гиперссылке. В нем мы и запустим установленный по умолчанию браузер и откроем в нем нужную страницу. Например, это можно сделать вот так:
private void linkLabel1_LinkClicked(object sender,
System.Windows.Forms.LinkLabelLinkClickedEventArgs e)
{
// Запускаем браузер и открываем в нем страницу.
System.Diagnostics.Process.Start(e.Link.LinkData.ToString());
}
Тут мы используем класс System.Diagnostics.Process, позволяющий запускать другие программу на нашем компьютере.
Урок 23. Как отобразить одно контекстное для нескольких элементов управления?
Для отображениения одного контекстного меню для различных элементов управления на форме не надо для каждого из них писать свой обработчик для щелчка мыши - достаточно написать один обработчик на все элементы управления. Кроме того (и это достаточно очевидный шаг) надо для каждого элемента управления установить свойство ContextMenu равным имени нашего контекстного меню.
Приведем конкретный пример.
Создайте обычное Windows-приложение. Добавьте на форрму несколько элементов управления. Пусть это для определенности будут label, textbox и кнопка. Кроме того, добавьте на форму элемент управления ContextMenu, к которому добавьте парочку пунктов - Item 1 и Item 2. При желании можно добавить и обработчики для данных пунктов меню.
В обработчик для загрузки формы добавьте следующий код:
private void Form1_Load(object sender, System.EventArgs e)
{
// Для каждого элемента управления
foreach (Control c in Controls)
{
// задаем контекстное меню.
c.ContextMenu = contextMenu1;
// Указываем для каждого элемента
// обработчик для правой кнопки мыши.
c.MouseDown +=
new MouseEventHandler(this.ShowPopupMenu);
}
}
Смысл кода достаточно ясен из комментариев - перебираем все элементы управления на форме и для каждого задаем контекстное меню и обработчик для правой кнопки мыши.
Остается добавить сам обработчик для нажатия кнопки мыши. Вот его код:
private void ShowPopupMenu(object sender,
System.Windows.Forms.MouseEventArgs e)
{
// Если нажата правая кнопка мыши.
if(e.Button == MouseButtons.Right)
{
Control c = (Control)sender;
// Если контекстное меню у элемента существует,
if(c.ContextMenu != null)
{
// то показываем его.
c.ContextMenu.Show(c, new Point(e.X, e.Y));
}
}
}
Обратите внимание, что обработчик мы назвали ShowPopupMenu - точно также, как имя метода, заданного при загрузке формы:
...
c.MouseDown += new MouseEventHandler(this.ShowPopupMenu);
...
Компилируем и запускаем программу. Получаем ожидаемый нами результат:
Урок 24. TreeView с checkbox'ами
Этот урок можно рассматривать как продолжение уроков 14 и 15.
Для того, чтобы у узлов элемента управления TreeView появились checkbox'ы в узлах, необходимо установить его свойство Checkboxes в true:
Теперь добавим радиционный код, добавляющий при загрузке формы несколько узлов и подузлов к нашему дереву:
private void Form1_Load(object sender, System.EventArgs e)
{
// Создаем узел верхнего уровня.
TreeNode treeNode = treeView1.Nodes.Add("Item1");
// Создаем два подузла для него.
TreeNode treeNode11 = treeNode.Nodes.Add("Item11");
TreeNode treeNode12 = treeNode.Nodes.Add("Item12");
// Создание подузлов для подузлов.
treeNode11.Nodes.Add("Item111");
treeNode11.Nodes.Add("Item112");
treeNode12.Nodes.Add("Item121");
treeNode12.Nodes.Add("Item122");
// Раскрываем все дерево.
treeNode.ExpandAll();
}
Текст более-менее должен быть ясен из комментариев.
Если запустить теперь нашу программу, то сразу будет видно, что у узлов дерева есть checkbox'ы.
Тепрь давайте напишем код, который будет ставить или убирать галочки у всех подчиненных подузлов некоторого узла. Т. е. если, например, поставить галочку у некоторого узла нашего дерева, то все подузлы этого узла также получат галочки. И наоборот - если убрать галочку у узла, то у всех его подузлов галочка тоже уберется. Вот код:
private void treeView1_AfterCheck(object sender,
System.Windows.Forms.TreeViewEventArgs e)
{
// Ставим галочку на всех подузлах.
SelectAllSubnodes(e.Node);
}
// Метод для установки галочки для всех подузлов.
void SelectAllSubnodes(TreeNode treeNode)
{
// Ставим или убираем отметку со всех подузлов.
foreach(TreeNode treeSubNode in treeNode.Nodes)
{
treeSubNode.Checked = treeNode.Checked;
}
}
Тут мы в методе treeView1_AfterCheck (ясно, что он вызывается при установке / снятии галочки у узла) вызываем написанный нами метод SelectAllSubnodes. Обратите внимание, что мы не используем рекурентный вызов методов - все будет работать и так.
Результат будет приблизительно такой:
Урок 25. Работаем с TabControl
На этом уроке мы с вами рассмотрим, как работать с элеменом управления TabControl:
Расположите его на форме. Первоначально на нем никаких закладок (табов) нет - их надо добавить. Сделать это можно двумя способами - или на этапе разработки программы, или программным способом на этапе работы программы.
Для добавления закладки на этапе разработки программы служит свойство TabPages:
При нажатии на кнопку с многоточием для данного свойства появляется соответствующее диалоговое окно. Интерфейс его понятен: для добавления очередной вкладки используем кнопку Add, для удаления - кнопку Remove, для изменения порядка вкладок - кнопки со стрелками, направленными вверх и вниз:
В этом же диалоговом окне вы можете для каждой добавленной вкладки установить ее свойства. Самым важным свойством, по всей видимости, является свойство Text, которое представляет из себя тот текст, который пользователь увидит на заголовке вкладки.
После закрытия этого диалогового окна накомпоненте TabControl появятся вкладки. Для добавления другого элемента управления на некоторую вкладку достаточно сначала щелкнуть на ее выступающей части и потом разместить на ней требуемый элемент управления (например, checkbox):
С этим уроком все.