Книга: C# для профессионалов. Том II
Другой пример
Разделы на этой странице:
Другой пример
Разобрав пример создания динамических элементов управления, давайте посмотрим, как эта техника может использоваться в приложениях.
Динамические элементы управления можно использовать для настройки интерфейса пользователя приложения в зависимости от некоторых данных среды выполнения. Классическим примером этого является добавление новых возможностей в панель инструментов, когда в каталог приложения вносятся новые дополнительные средства (plug-ins) или модули. Например, установка Adobe Acrobat на компьютере может автоматически добавлять в панель инструментов Word кнопку для создания документа Acrobat.
Другим примером может быть утилита администрирования базы данных. Когда утилита соединяется с базой данных, в интерфейс пользователя должна быть добавлена кнопка, представляющая каждую имеющуюся внутри базы данных таблицу. Или можно создать множество элементов управления текстовых полей с именами всех файлов XML, содержащихся в определенном каталоге, и т.д.
В этом примере мы собираемся создать приложение, загружающее с диска сборку, просматривающее сборку в поисках типов данных, которые наследуют от System.Windows.Forms.Control
, и выводящее кнопку в форме для каждого найденного типа. Нажатие на кнопку будет вызывать экземпляр элемента управления и выводить его в форму.
Создание проекта
Создадим новый проект Visual C# — Windows Application и назовем его ControlLoader
. В самом начале мы не будем размещать в новой форме никаких элементов управления, но можем изменить свойство Text на что-нибудь типа "Control Container".
Итак, добавим следующие члены в форму:
public class Form1 : System.Windows.Forms.Form {
// члены ...
private ArrayList _buttons = new ArrayList();
private int _nextY = ButtonSpacing;
private Control _containedControl;
// константы ...
const int ButtonHeight = 25;
const int ButtonSpacint = 5;
const int ButtonWidth = 200;
Мы имеем список кнопок, которые добавляются в ArrayList
с именем _buttons
. При добавлении каждой кнопки к форме необходимо разместить ее в правильной у-координате, т.е. _nextY
. Рассмотрим только один элемент управления в конкретный момент, который будет содержаться в _containedControl
. Наконец, мы используем метрику, которая описывает компоновку кнопок, и она задается тремя константами внизу.
Сами кнопки будут создаваться из нового класса, производного от System.Windows.Forms.Button
. Этот новый класс называется TypeButton
и имеет дополнительное свойство ControlType
, которое содержит объект System.Type
. Этот объект Type
представляет элемент управления в загружаемой сборке. Создадим новый класс с именем TypeButton
и добавим ссылку на пространство имен System.Windows.Forms
.
using System;
using System.Windows.Forms;
Затем добавим код:
public class TypeButton System.Windows.Forms.Button {
public Type _controlType;
public TypeButton() {
}
// ControlType — получить или задать свойство ...
public Type ControlType {
get {
return _controlType;
}
set {
_controlType = value;
this.Text = _controlType.FullName;
}
}
}
Как можно видеть, задавая свойство ControlType
, мы изменяем текст кнопки, чтобы он стал полным названием типа.
Метод, который нужен для создания TypeButton
, создает экземпляр элемента управления. Добавим этот метод, использующий System.Activator
для создания экземпляра класса и преобразующий его в System.Windows.Forms.Control
:
// CreateInstance — создание экземпляра типа данных ...
public Control CreateInstance() {
// возвращает экземпляр нового элемента управления ...
return (Control)Activator.CreateInstance(ControlType);
}
Добавление кнопок
Для первого проверочного запуска добавим TypeButton
, который представляет экземпляр элемента управления System.Windows.Forms.DataGrid
. Это позволит протестировать логику того, что делается, не вдаваясь в дополнительные трудности, связанные с загрузкой сборки и просмотром типов данных.
Метод Form1.AddType
будет получать объект System.Type
и добавлять новый объект TypeButton
в форму. Во-первых, необходимо создать экземпляр TypeButton
и задать его свойство ControlType
новым типом:
// AddType - добавить кнопку типа в компоновку ...
public void AddType(Type ControlType) {
// первое: создать новую кнопку типа ...
TypeButton button = new TypeButton();
button.ControlType = ControlType;
Во-вторых, нужно добавить TypeButton
в ArrayList
, который содержит список кнопок:
// второе: добавить эту кнопку в массив
_buttons.Add(button);
После этого можно поместить в форму кнопку и добавить ее в список элементов управления формы:
// теперь разместим кнопку
button.Left = ButtonSpacing;
button.Width = ButtonWidth;
button.Top = _nextY;
button.Height = ButtonHeight;
// настроить следующее значение у ...
_nextY += (ButtonHeight + ButtonSpacing);
// вывести кнопку ...
this.Controls.Add(button);
Наконец, необходимо присоединить событие click
(нажатие) кнопки таким образом, чтобы мы могли иметь экземпляр элемента управления, который он представляет:
// затем присоединяем обработчик события ...
button.Click += new EventHandler(this.ButtonClick);
}
Пока еще мы не создали ButtonClick
, — сделаем это сейчас:
// ButtonClick — вызывается всякий раз при нажатии кнопки ...
protected void ButtonClick(object sender, System.EventArgs e) {
// преобразовать sender в кнопку типа ...
TypeButton button = (TypeButton)sender;
Нашей первой задачей является преобразование sender
в TypeButton
. Это позволит использовать CreateInstance
для создания элемента управления. Если мы уже имеем элемент управления, необходимо сначала удалить его из списка элементов управления формы:
// если уже имеется содержащийся элемент управления, удалим его ...
if (_containedControl != null)
Controls.Remove(_containedControl);
Создаем элемент управления:
// создать экземпляр нового элемента управления...
_containedControl = button.CreateInstance();
Наконец, мы можем поместить элемент управления в форму.
// поместить элемент управления на форме ...
_containedControl.Left = ButtonWidth + (3 * ButtonSpacing);
_containedControl.Top = ButtonSpacing;
_containedControl.Width = this.Width - _containedControl.Left - (4 * ButtonSpacing);
_containedControl.Height = this.Height - (8 * ButtonSpacing);
this.Controls.Add(_containedControl);
}
Тестирование полученного кода
Прежде чем можно будет увидеть окончательный вариант сделанного, необходимо добавить кнопку в форму. Используем элемент управления System Windows.Forms.DataGrid
. Добавим следующий код в Form1
:
private void Form1_Load(object sender, System.EventArgs e) {
// при загрузке добавить тип кнопки ...
DataGrid grid = new DataGrid();
AddType(grid.GetType());
}
Теперь закончим проект. Нажав на кнопку System.Windows.Forms.DataGrid
, увидим:
- 8.2.3. Учебный пример: Glade
- Как перейти от одной выполняющейся программы к другой?
- Пример 9-11. Преобразование графических файлов из одного формата в другой, с изменением имени файла
- Пример 10-15. Другой пример цикла while
- Пример установочного скрипта
- Пример из практики
- ПРИМЕР ПРОСТОЙ ПРОГРАММЫ НА ЯЗЫКЕ СИ
- Примеры получения статистики
- Пример применения метода «пять почему»
- Пример 12-8. Частота встречаемости отдельных слов
- 1.2.5. Пример программы
- Пример 17-10. Блочный комментарий