new System.EventHandler(this.DynamicButton_Click);
newButton.MouseEnter +=
new System.EventHandler(this.DynamicButton_Enter);
newButton.MouseLeave +=
new System.EventHandler(this.DynamicButton_Leave);
Теперь, если снова выполнить приложение, в журнал будут добавляться сообщения по мере перемещения по кнопкам.
Другой пример
Разобрав
пример создания динамических элементов управления, давайте посмотрим, как эта техника может использоваться в приложениях.
Динамические элементы управления можно использовать для настройки интерфейса пользователя приложения в зависимости от некоторых данных среды выполнения. Классическим примером этого является добавление новых возможностей в панель инструментов, когда в каталог приложения вносятся новые дополнительные средства (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 {
// возвращает экземпляр нового элемента управления ...
, который представляет экземпляр элемента управления
System.Windows.Forms.DataGrid
. Это позволит протестировать логику того, что делается, не вдаваясь в дополнительные трудности, связанные с загрузкой сборки и просмотром типов данных.
Метод
Form1.AddType
будет получать объект
System.Type
и добавлять новый объект
TypeButton
в форму. Во-первых, необходимо создать экземпляр
TypeButton
и задать его свойство
ControlType
новым типом:
// AddType - добавить кнопку типа в компоновку ...