Контролы для windows forms

Содержание
  1. Программное добавление элементов управления в Windows Forms во время выполнения с помощью Visual C#
  2. Сводка
  3. Требования
  4. Создание приложения Windows Forms
  5. Настройка свойств формы и элемента управления
  6. Добавление элементов управления в форму
  7. Проверка работы
  8. Ссылки
  9. Практическое руководство. Добавление элементов управления в формы Windows Forms. How to: Add Controls to Windows Forms
  10. Рисование элемента управления в форме To draw a control on a form
  11. Перетаскивание элемента управления в форму To drag a control to a form
  12. Добавление элемента управления в форму программным способом To add a control to a form programmatically
  13. Технология Клиент-Сервер 2004’1 Home Поиск Издания Контакты k-press.ru
  14. Введение
  15. Базовый класс контролов System.Windows.Forms.Control.
  16. Дескриптор окна контрола
  17. Обработка сообщений Windows.
  18. Свойства, методы и события, управляющие размерами контрола
  19. Отрисовка контрола
  20. Контрол как контейнер
  21. Ambient- и Default-свойства
  22. Основные классы иерархии контролов в .NET
  23. Заключение

Программное добавление элементов управления в Windows Forms во время выполнения с помощью Visual C#

Эта статья поможет программным способом добавлять и настраивать элементы управления в форме Windows Forms с помощью Visual C#.

Исходная версия продукта: Visual C #
Исходный номер статьи базы знаний: 319266

Сводка

В этой статье приведены пошаговые инструкции по добавлению и настройке нескольких часто используемых элементов управления в форме Windows Forms. В примере кода отсутствует обработка событий.

Пакет средств разработки программного обеспечения (SDK) Microsoft .NET Framework предоставляет множество визуальных элементов управления, которые можно использовать для создания приложения Windows Forms. Вы можете добавлять и настраивать элементы управления во время конструирования в Visual Studio .NET или в Visual Studio. Вы можете добавлять и настраивать элементы управления программным способом во время выполнения.

Требования

В этой статье предполагается, что вы знакомы со следующими разделами:

  • Синтаксис Visual C#
  • Среда Visual Studio .NET, среда Visual Studio
  • Назначение распространенных элементов управления Visual C#

Создание приложения Windows Forms

Запустите Visual Studio .NET или Visual Studio и создайте новый проект приложения Visual C# для Windows с именем винконтролс. По умолчанию форма Form1 добавляется в проект.

Дважды щелкните Form1, чтобы создать и просмотреть Form1_Load процедуру обработки события.

Добавьте в класс переменные частных экземпляров Form1 для работы с общими элементами управления Windows. Form1 Класс запускается следующим образом:

Код должен быть изменен в Visual Studio. Когда вы создаете проект Windows Forms, Visual C# добавляет по умолчанию одну форму в проект. Эта форма называется Form1. Два файла, представляющие форму, называются Form1.CS и Form1.Designer.CS. Вы пишете свой код в Form1.CS. Файл Designer.CS — это место, в котором конструктор Windows Forms записывает код, который реализует все действия, выполненные путем добавления элементов управления. Дополнительные сведения о конструкторе Windows Forms в Visual C# приведены в статье Создание проекта (Visual c#).

Настройка свойств формы и элемента управления

Нахождение Form1_Load процедуры обработки события и добавление в процедуру следующего кода для настройки внешнего вида элемента управления формы:

Добавьте следующий код в Form1_Load процедуру обработки события для настройки внешнего вида элемента управления «Кнопка»:

Добавьте следующий код для настройки внешнего вида элемента управления TextBox в Form1_Load :

Добавьте следующий код для настройки внешнего вида элемента управления ListBox в Form1_Load :

Добавьте следующий код, чтобы настроить внешний вид элемента управления CheckBox в Form1_Load :

Добавьте следующий код, чтобы настроить внешний вид элемента управления Label в Form1_Load :

Добавление элементов управления в форму

Добавьте следующий код, чтобы добавить каждый объект в Controls массив формы в конце Form1_Load :

Проверка работы

Чтобы убедиться, что пример работает, выберите команду начать в меню Отладка .

  • Хотя отображаются форма и элементы управления, в настоящее время они не выполняют никаких действий, так как вы не записали обработчики событий.
  • Помните, что позиции этих элементов управления являются статическими. Чтобы сделать их более надежными при растяжении формы, сделайте точки динамическими относительно положения формы. Если элементы управления статичны, растягивание формы может помешать отображению других элементов управления в форме.

Ссылки

Дополнительные сведения об использовании элементов управления программным способом можно найти в разделе приложения Windows в разделе Visual C# справочной документации по Visual Studio .NET Online или в справочной документации по Visual Studio Online.

Практическое руководство. Добавление элементов управления в формы Windows Forms. How to: Add Controls to Windows Forms

Большинство форм разрабатываются путем добавления элементов управления на поверхность формы для определения пользовательского интерфейса. Most forms are designed by adding controls to the surface of the form to define a user interface (UI). Элемент управления — это компонент в форме, используемый для вывода информации или ввода данных пользователем. A control is a component on a form used to display information or accept user input. Дополнительные сведения об элементах управления см. в разделе элементы управления Windows Forms. For more information about controls, see Windows Forms Controls.

Рисование элемента управления в форме To draw a control on a form

Откройте форму. Open the form. Дополнительные сведения см. в разделе инструкции. отображение Windows Forms в конструкторе. For more information, see How to: Display Windows Forms in the Designer.

В области элементов щелкните элемент управления, который необходимо добавить в форму. In the Toolbox, click the control you want to add to your form.

В форме щелкните место, где должен располагаться левый верхний угол элемента управления, и перетащите его в то место, где должен располагаться правый нижний угол элемента управления. On the form, click where you want the upper-left corner of the control to be located, and drag to where you want the lower-right corner of the control to be located.

Элемент управления добавляется в форму с указанными расположением и размером. The control is added to the form with the specified location and size.

Для каждого элемента управления определен размер по умолчанию. Each control has a default size defined. Можно добавить элемент управления в форму в размер элемента управления по умолчанию, перетащив его из области элементов в форму. You can add a control to your form in the control’s default size by dragging it from the Toolbox to the form.

Перетаскивание элемента управления в форму To drag a control to a form

Откройте форму. Open the form. Дополнительные сведения см. в разделе инструкции. отображение Windows Forms в конструкторе. For more information, see How to: Display Windows Forms in the Designer.

На панели элементов щелкните нужный элемент управления и перетащите его в форму. In the Toolbox, click the control you want and drag it to your form.

Элемент управления добавляется в форму в указанном расположении в его размер по умолчанию. The control is added to the form at the specified location in its default size.

Можно дважды щелкнуть элемент управления на панели элементов , чтобы добавить его в левый верхний угол формы в его размер по умолчанию. You can double-click a control in the Toolbox to add it to the upper-left corner of the form in its default size.

Кроме того, можно динамически добавлять элементы управления в форму во время выполнения. You can also add controls dynamically to a form at run time. В следующем примере кода TextBox элемент управления будет добавлен в форму при Button щелчке элемента управления. In the following code example, a TextBox control will be added to the form when a Button control is clicked.

Читайте также:  Visual studio code linux path

Следующая процедура требует наличия формы с элементом управления Button , Button1 уже размещенным в ней. The following procedure requires the existence of a form with a Button control, Button1 , already placed on it.

Добавление элемента управления в форму программным способом To add a control to a form programmatically

В методе, обрабатывающем событие кнопки Click в классе формы, вставьте код, аналогичный приведенному ниже, чтобы добавить ссылку на переменную элемента управления, задать элемент управления Location и добавить элемент управления. In the method that handles the button’s Click event within your form’s class, insert code similar to the following to add a reference to your control variable, set the control’s Location , and add the control.

Можно также добавить код для инициализации других свойств элемента управления. You can also add code to initialize other properties of the control.

Вы можете предоставить локальному компьютеру угрозу безопасности через сеть, обратившись к вредоносной программе UserControl . You might expose your local computer to a security risk through the network by referencing a malicious UserControl . Это будет проблемой только в случае, если злоумышленник создает вредоносный пользовательский элемент управления, а затем добавляет его в проект по ошибке. This would only be a concern in the case of a malicious person creating a damaging custom control, followed by you mistakenly adding it to your project.

Технология Клиент-Сервер 2004’1
Home Поиск Издания Контакты k-press.ru

Авторы: Голованов Михаил
Евгений Веселов

Введение

В предыдущей статье Владислава Чистякова рассматривалось создание компонентов в .NET (статья Владислава Чистякова опубликована в журнале RSDN Magazine № 3 за 2002 год). Продолжая дело, начатое им, рассмотрим наиболее важные аспекты создания контролов.

Для начала определимся с терминологией. В .NET контрол – это компонент, представляющий часть пользовательского интерфейса (GUI). Аналогом англоязычного термина control в русском языке является «элемент управления», однако такой перевод длиннее, и труднее произносится, поэтому мы будем использовать, может и не слишком удачную, кальку контрол.

Контролы делятся на два подкласса: WinForms-контролы и ASP.NET-контролы. Первые соответственно предназначены для использования в обычных оконных приложениях, а вторые – в Web-приложениях. В данной статье мы рассмотрим WinForms-контролы, поэтому термин «контрол» далее будет использоваться в контексте WinForms.

Можно выделить три основные группы разрабатываемых контролов:

  • Составные контролы (Composite controls). Объединяют несколько контролов, повышая удобство их использования. Примером такого контрола может служить строка ввода (Edit) с надписью (Label). Создав составной компонент, объединяющий эти два контрола, можно избавить прикладного программиста от необходимости выполнения рутинной работы по размещению и выравниванию контролов.
  • Изменение поведения стандартных компонентов (Authoring). Часто в существующих компонентах хочется «доработать напильником» некоторые мелочи. Например, установить сразу значения некоторых свойств, отличные от значений по умолчанию.
  • Создание новых контролов, обладающих какой-либо уникальной функциональностью.

Базовый класс контролов System.Windows.Forms.Control.

Базовым классом для контролов является System.Windows.Forms.Control – прямой потомок System.ComponentModel.Component. System.Windows.Forms.Control содержит скелет контрола, на который можно наращивать «мясо». Рассмотрим класс System.Windows.Forms.Control более подробно.

Дескриптор окна контрола

Поскольку контрол представляет собой обособленную часть пользовательского интерфейса, он имеет окно и связанный с окном дескриптор.

Получить значение дескриптора окна можно, используя свойство Handle, объявленное как:

Поскольку созданное окно потребляет ресурсы системы, то можно создавать окно не в конструкторе контрола, а позже, когда оно действительно понадобится. Создать дескриптор окна контрола можно, вызвав метод CreateHandle, объявленный как:

Можно переопределить данный метод в собственном контроле, при этом нужно не забывать вызвать метод CreateHandle. Как правило, не приходится вызывать CreateHandle непосредственно, так как он вызывается методом CreateControl. Дескриптор также будет создан автоматически и при обращении к свойству Handle.

Метод DestroyHandle освобождает дескриптор окна. Декларация метода:

Некоторые оконные опции можно задать только до создания окна. Поэтому иногда бывает необходимо пересоздать окно. Для этого предназначен метод:

Проверить, создан ли дескриптор окна контрола, можно с помощью свойства:

public bool IsHandleCreated

указывает на то, что в данный момент ведется пересоздание окна, и нежелательны какие-либо обращения к дескриптору окна.

позволяет получить и настроить свойства создаваемого контрола. Установленные параметры используются при создании окна контрола. Наиболее часто при создании собственных контролов приходится иметь дело с полем ClassName возвращаемого класса CreateParams. Данное свойство задает класс Windows-контрола, оберткой которого является .NET-контрол. Свойства Style и ExStyle задают стиль создаваемого Windows-контрола и должны быть хорошо известны программистам, разрабатывавшим контролы под Win32.

С дескриптором контрола также связаны два события:

оповещающие о создании и уничтожении дескриптора окна. Как нетрудно догадаться методы диспетчеризации этих событий называются OnHandleCreated и OnHandleDestroyed и объявлены как:

их можно переопределить в наследнике и обрабатывать данные сообщения без подключения обработчиков событий.

В классе System.Windows.Forms.Control определены два статических метода для поиска контрола по его handle. Первый:

ищет контрол, имеющий переданный в параметре handle дескриптор окна. Однако для контролов, имеющих несколько дескрипторов, он работает некорректно. Если вам нужно найти такие контролы, то следует использовать второй метод поиска:

В качестве небольшого примера работы с дескриптором окна создадим текстовую метку, отображающую свой дескриптор.

Для этого переопределим ее свойство Text:

На рисунке 1 приведен скриншот компонента на этапе разработки.

Обработка сообщений Windows.

Как известно, в Windows взаимодействие с приложениями основано на пересылке сообщений. Приложение получает от OC сообщения и обрабатывает их, используя оконную процедуру. Класс Control содержит несколько методов работы с сообщениями.

Для демонстрации работы контрола с сообщениями Windows введем дополнительное свойство:

Это свойство позволяет задать строку ввода для отображения строк тестовых сообщений, которые будет выводить контрол. Для удобства вывода строк сообщений определим метод LogMessage:

Оконная процедура контрола объявлена как:

Как видно из декларации, контрол может переопределить оконную процедуру. В нашем примере мы переопределили оконную процедуру таким образом, что она выводит тестовые сообщения и вызывает оконную функцию своего предка (класса Control).

Еще одним методом, относящимся к обработке сообщений, является метод:

Он позволяет перекрыть оконную процедуру по умолчанию и вызывается из метода WndProc. При этом мы получаем доступ к обработке сообщений Win32 окна контрола.

Переопределим метод DefWndProc нашего контрола следующим образом:

Для реакции контрола на сообщения Windows можно воспользоваться событием OnNotifyMessage. Диспетчер события декларирован следующим образом:

Генерация события происходит в методе WndProc, если в стиле контрола установлен флаг EnableNotifyMessage. Данный флаг устанавливается в конструкторе:

Диспетчер события мы перекроем следующим образом:

Таким образом, мы перекрыли методы нашего контрола так, что можем визуально отслеживать порядок вызова методов обработки сообщений. Ниже приведен скриншот главного окна демонстрационного приложения:

Как видно из скриншота, при получении сообщения вызывается метод WndProc. Метод проверяет значение флага EnableNotifyMessage, и если последний установлен, вызывает OnNotifyMessage. Далее вызывается метод DefWndProc, после чего обработка сообщения завершается.

К сожалению, класс Control не имеет метода отправки сообщения, хотя как показывает исследование кода класса рефлектором, активно использует native метод Win32 SendMessage. В бета-версиях .NET Framework метод SendMessage был доступен и прикладным программистам, однако его применение дает возможность практически прямого доступа к Win32, что может привести к серьезным дырам в безопасности и надежности приложений .NET. В окончательной версии это было устранено.

Свойства, методы и события, управляющие размерами контрола

Класс System.Windows.Forms.Control определяет несколько свойств, методов и событий для управления размерами контрола. В таблицах 1, 2, 3, 4 приведено описание этих свойств, методов и событий.

Отрисовка контрола

Наиболее общим случаем, когда требуется самостоятельно заниматься отрисовкой контрола, является случай разработки компонента «с нуля». Для отрисовки контрола необходимо переопределить метод OnPaint.

Для управления аспектами отрисовки контрола предназначен метод

Параметр ControlStyles flag должен содержать набор устанавливаемых битовых флагов, задающих параметры отрисовки контрола.

Параметр value указывает на необходимость установить заданные в ControlStyles параметры отрисовки.

В таблице 5 приведено описание флагов ControlStyles.

Свойство Описание
public int Top Координата верхней границы контрола.
public int Left Координата левой границы контрола.
public int Bottom Координаты нижней границы контрола.
public int Right Координаты правой границы контрола.
public int Height Высота контрола.
public int Width Ширина контрола.
public Rectangle ClientRectangle Клиентская область контрола, т.е. область в которой контрол может отрисовывать свое содержимое. В клиентскую область не входят полосы прокрутки, меню, заголовки (title bars).
public Size ClientSize Размер клиентской области.
public Point Location Координаты левого верхнего угла контрола.
public Region Region Регион контрола. Задает форму окна контрола.
public Size Size Размер контрола.
[C#]protected virtual Size DefaultSize Размер контрола по умолчанию.

Таблица 2. Методы управления размерами контрола.

Метод Описание
public Point PointToClient( Point p); Метод преобразует координаты точки из экранных координат в систему координат контрола.
public Point PointToScreen( Point p); Метод преобразует координаты точки из системы координат контрола в экранные координаты.
public Rectangle RectangleToClient( Rectangle r); Метод преобразует координаты прямоугольника из экранной в систему координат контрола.
public Rectangle RectangleToScreen( Rectangle r); Метод преобразует координаты прямоугольника из системы координат контрола в систему координат экрана.
public void Scale(float ratio);public void Scale(float dx, float dy); Метод масштабирования контрола (растяжение/сжатие).
public void SetBounds( int x, int y, int width, int height, BoundsSpecified specified);public void SetBounds( int x, int y, int width, int height); Метод установки границ контрола. Параметр specified определяет, какие параметры границ устанавливать.
protected virtual void ScaleCore( float dx, float dy); Выполняет работу по масштабированию контрола.
protected virtual void SetBoundsCore( int x, int y, int width, int height, BoundsSpecified specified); Выполняет работу по изменению границ контрола.
protected virtual void SetClientSizeCore(int x, int y); Устанавливает размер клиентской области контрола.

Таблица 3. События, относящиеся к управлению размерами контрола.

Событие Описание
public event EventHandler Move; Событие, возникающее при перемещении контрола.
public event EventHandler Resize; Событие изменения размеров контрола.
public event EventHandler SizeChanged; Событие, возникающее после измения свойства Size.

Таблица 4. Основные свойства позиционирования контрола на форме и управления фокусом ввода.

Свойство Описание
public virtual AnchorStyles Anchor Углы формы, к которым заякорен контрол.
public virtual DockStyle Dock Настройки выравнивания контрола на форме.
public bool CanFocus Определяет, может ли контрол принимать фокус ввода.
public bool CanSelect Определяет, может ли контрол быть выбранным. Свойство возвращает true, если у контрола установлен стиль ControlStyles.Selectable. Такие контролы как Panel, GroupBox, PictureBox, ProgressBar, Splitter, Label, LinkLabel не могут быть выбраны.

Таблица 5. Флаги ControlStyles.

Наименование флага Описание Значение
AllPaintingInWmPaint Если данный флаг установлен, контрол игнорирует сообщение WM_ERASEBKGND для уменьшения «шума» (flicker). Данный флаг должен быть установлен в комбинации с флагом UserPaint. 8192
CacheText Кеширование текста контрола. При установке данного флага текст контола кэшируются. Кеширование увеличивает скорость отрисовки, но может порождать проблемы синхронизации. По умолчанию флаг сброшен. 16384
ContainerControl Данный флаг указывает на то, что контрол является контейнером. 1
DoubleBuffer Установка данного флага буферизирует отрисовку контрола, позволяя снизить мерцания и «шумы» отрисовки. 65536
EnableNotifyMessage Установка данного флага приводит к вызову OnNotifyMessage из WndProc при получении контролом сообщений. По умолчанию сброшен. 32768
FixedHeight, FixedWidth Фиксированная высота/ширина контрола. При auto-scale высота/ширина не меняются. 64, 32
Opaque Прозрачность контрола. При установке флага подложка контрола не прорисовывается. 4
ResizeRedraw Отрисовка контрола при изменении его размеров. 16
Selectable Контрол может получать фокус ввода. 512
StandardClick Контрол использует стандартное поведение при щелчке мышью. 256
StandardDoubleClick Контрол использует стандартное поведение при двойном щелчке мышью. 4096
SupportsTransparentBackColor Цвет фона контрола берется в качестве «прозрачного» цвета. Таким образом эмулируется прозрачность. Установка данного флага должна сопровождаться установкой флага . 2048
UserMouse Контрол самостоятельно обрабатывает события мыши, операционной системе не нужно обрабатывать события мыши данного контрола. 1024
UserPaint Контрол отрисовывает себя сам полностью сам. 2

При создании контролов наиболее часто используются флаги AllPaintingInWmPaint, CacheText, DoubleBuffer, Opaque, ResizeRedraw, SupportsTransparentBackColor, UserPaint.

В качестве иллюстрации отрисовки контрола мы создадим контрол, отображающий картинку из ресурсов сборки. Поместим в ресурсы сборки картинку. Для этого правой кнопкой мыши вызовем контекстное меню сборки и выберем из него пункт Add/Add Existing Item… С помощью появившегося диалога выберем любую картинку. В данном примере была выбрана картинка с именем MS.jpg. Далее выберем пункт Properties из контекстного меню этой картинки. В появившемся окне Properties установим свойство «Build Action» в значение «Embedded Resource». Теперь выбранная нами картинка будет включена в сборку в виде внедренного ресурса. В качестве базового класса для нашего контрола мы выбрали класс System.Windows.Forms.Control.

Для отображения картинки переопределим метод OnPaint следующим образом:

Для удобства изложения строки пронумерованы. Метод OnPaint получает в качестве параметра объект PaintEventArgs. Он содержит два свойства:

  • Graphics – «полотно» рисования контрола.
  • ClipRectangle – прямоугольная область отсечения отрисовки.

В строке 1 вызывается метод OnPaint базового класса. Это позволит избавиться от необходимости выполнять базовую отрисовку. В строке 2 мы получаем текущую сборку, а в строке 3 извлекаем из сборки, включенный в нее ресурс-картинку. Строки 2 и 3 не имеют непосредственного отношения к отрисовке контрола, вся полезная работа происходит в строках 4 и 5. В строек 4 создается кисть, предназначенная для отрисовки картинки, а в строке 5, с помощью «полотна» рисования контрола, картинка выводится на экран. Как видите, ничего сложного в собственной отрисовке контрола нет. Полотно рисования Graphics позволяет использовать для отрисовки все возможности GDI+, что делает задачу написания отрисовки контрола простой и необременительной задачей.

Как вы, наверно, уже заметили, метод OnPaint объявлен защищенным (protected), то есть вызвать его можно только из класса контрола и его потомков. С одной стороны, это правильно, так как прикладным программистам, которые будут использовать ваш контрол, явно вызывать метод отрисовки ни к чему. Однако при этом возникает вопрос: как осуществлять собственную отрисовку дочерних контролов в том случае, когда контрол представляет собой совокупность нескольких стандартных контролов (composite control). Мы не можем переопределить методы OnPaint составляющих контрола. В данном случае применяется второй способ отрисовки – добавление собственного обработчика в список обработчиков события Paint. Для каждого контрола, входящего в составной контрол, можно добавить обработчик Paint и в нем производить дорисовку. Из-за тривиальности такой задачи мы не будем приводить пример ее реализации.

Контрол как контейнер

Контрол может выступать в качестве контейнера для других контролов и компонентов. Ярким примером контрола-контейнера является панель (Panel). Панель управляет контролами, размещенными на ней. Базовые механизмы поддержки контейнеров компонентов реализованы в классе Contol.

В классе Control объявлена коллекция Controls предназначенная для хранения и управления своими дочерними контролами.

Класс Control.ControlCollection представляет собой типизированную коллекцию. Перед добавлением нескольких контролов в контейнер рекомендуется вызывать метод SuspendLayout, а сразу после добавления – метод ResumeLayout. Вызов метода SuspendLayout останавливает работу менеджера выравнивания (layout logic), отвечающего за обработку свойств Size, Location, Anchor, или Dock дочерних контролов, а метод ResumeLayout возобновляет работу менеджера. Пример работы с коллекцией и менеджером слоев можно увидеть, открыв код метода InializeComponent любой формы, содержащей контролы.

В коллекции Control.ControlCollection могут находиться только элементы-наследники System.Windows.Forms.Control. Сразу возникает вопрос – каким образом хранятся и обрабатываются невизуальные компоненты наподобие Timer? Ответ на этот вопрос можно увидеть все в том же коде формы. В классе формы объявлено поле:

Все невизуальные компоненты добавляются в контейнер components. Пример:

Далее в методе Dispose, происходит освобождение ресурсов занятых невизуальными контролами.

Кроме хранения контролов, необходимо так же управлять фокусом ввода и другими визуальными аспектами работы контейнера. Данная функциональность реализована в классе System.Windows.Forms.ContainerControl.

Ambient- и Default-свойства

Одной из малодокументированных областей, часто вызывающей вопросы при разработке контролов, является вопрос установки значений свойства по умолчанию.

Предположим, что у контрола есть свойство ExtraColor. Значение по умолчанию данного свойства необходимо установить равным значению BackColor формы, на которой расположен контрол.

Попытаемся задать значение по умолчанию, использовав атрибут DefaultValue. Объявим свойство следующим образом:

Изменив значение свойства, мы увидим, что пункт контекстного меню Reset доступен, и позволяет нам восстановить значение свойства по умолчанию. Но это замечательное решение будет работать, только если значение по умолчанию известно заранее. При этом (при размещении контрола на форме) в код инициализации контрола будет добавлена строка:

То есть мы явно задаем значение свойства ExtraColor. Однако если мы внимательно посмотрим на код инициализации формы, то нигде не обнаружим задания ее свойства BackColor. Аналогичного эффекта хотелось бы добиться и для свойства ExtraColor нашего контрола. Проблема заключается в том, что значение по умолчанию свойства BackColor формы не известно заранее, и явное задание ExtraColor при инициализации нашего контрола не может решить поставленной нами задачи.

Для случая, когда значение свойства контрола по умолчанию не известно заранее, а должно браться из внешнего по отношению к контролу источника, предназначен атрибут AmbientValue. Объявим свойство с использованием этого атрибута:

Кроме этого необходимо реализовать метод:

Этот метод сообщает среде разработки о необходимости явной сериализации значения свойства. Метод возвращает true только в том случае, если значения свойства задано пользователем явно.

Поместим контрол на форму. При этом значение свойства ExtraColor будет браться из свойства BackColor формы, и, в отличие от случая использования атрибута DefaultValue, явного задания значения свойства в методе InitializeComponent формы не произойдет. Изменим значение свойства ExtraColor и убедимся, что в методе InitializeComponent формы добавилась строка, явно инициализирующая значение ExtraColor. Затем в контекстном меню свойства выберем пункт Reset, вернув значение свойства в состояние по умолчанию. Строка явной инициализации значения свойства ExtraColor исчезнет, а его значение снова будет браться из значения BackColor формы, что и требовалось реализовать.

Основные классы иерархии контролов в .NET

Классы-наследники System.Windows.Forms.Control представляют собой либо базовые классы для создания контролов (System.Windows.Forms.ButtonBase – базовый класс для создания кнопок, System.Windows.Forms.TextBoxBase – базовый класс для создания строк ввода текста), либо готовые контролы:

  • System.Windows.Forms.DataGrid
  • System.Windows.Forms.DateTimePicker
  • System.Windows.Forms.GroupBox
  • System.Windows.Forms.Label
  • System.Windows.Forms.ListControl
  • System.Windows.Forms.ListView
  • System.Windows.Forms.MonthCalendar
  • System.Windows.Forms.PictureBox
  • System.Windows.Forms.PrintPreviewControl
  • System.Windows.Forms.ProgressBar
  • System.Windows.Forms.ScrollBar
  • System.Windows.Forms.Splitter
  • System.Windows.Forms.StatusBar
  • System.Windows.Forms.TabControl
  • System.Windows.Forms.ToolBar
  • System.Windows.Forms.TrackBar
  • System.Windows.Forms.TreeView

Большинство из вышеперечисленных контролов представляют собой .NET обертки над Win32 контролами.

В качестве небольшой иллюстрации возможностей наследования от классов-наследников Control мы разработали компонент текстовой метки с тенью. Ниже приведен код компонента.

В методе отрисовки OnPaint, помимо стандартной отрисовки контрола, вызываемой через base.OnPaint, мы дорисовываем тень, смещая ее вниз и вправо. Получение цвета тени осуществляется вызовом Color.FromArgb(70, this.ForeColor). Наличие остального кода связано с различными режимами выравнивания текстовой метки по горизонтали и вертикали. Таким образом, пример демонстрирует возможность модификации вида стандартных контролов.

Гораздо более интересен с точки зрения разработчиков компонентов класс System.Windows.Forms.ScrollableControl.

Данный класс является базовым для всех контролов, поддерживающих автоматическую прокрутку содержимого (auto-scroll). Для поддержки автоматического отображения полос прокрутки введено свойство AutoScroll. Свойство AutoScrollMinSize задает минимальные размеры контрола, при которых отображаются полосы прокрутки. Свойства VScroll и HScroll позволяют управлять видимостью вертикальной и горизонтальной полос прокрутки соответственно.

Класс ContainerControl является непосредственным потомком ScrollableControl и реализует поддержку контейнера контролов. Кроме того, класс управляет передачей фокуса ввода дочерними контролам. Класс реализует интерфейс IContainerControl, содержащий одно свойство ActiveControl и один метод ActivateControl().

Свойство ActiveControl позволяет получать и изменять дочерний контрол, имеющий фокус ввода. Метод:

предназначен для переключения фокуса ввода на указанный в параметре дочерний контрол. Класс ContainerControl имеет четырех наследников:

  • System.Windows.Forms.Form
  • System.Windows.Forms.PropertyGrid
  • System.Windows.Forms.UpDownBase
  • System.Windows.Forms.UserControl

Наиболее часто при разработке компонентов используются классы System.Windows.Forms.Form и System.Windows.Forms.UserControl. Класс System.Windows. Forms.Form является базовым классом для создания форм. Класс System.Windows.Forms.UserControl является базовым классом для создания композитных контролов.

Композитный контрол представляет собой повторно используемый контейнер, содержащий набор контролов с заранее установленными значениями свойств. В качестве примера создания композитного контрола разработаем контрол-строку ввода с текстовой меткой. Для этого необходимо в среде VS.NET создать новый проект, либо в существующем проекте, используя пункт контекстного меню Add/Add UserControl, добавить заготовку композитного контрола. В появившемся диалоге создания контрола зададим имя контрола – CompositeControl. При этом в проект будет добавлен файл CompositeControl.cs, содержащий код нашего контрола. Помимо текстового представления доступен и визуальный редактор контрола. Разместим с его помощью на контроле строку ввода textBox1 и текстовую метку label1.

Даже в таком виде контрол уже может использоваться. Однако нам необходимо обеспечить возможность доступа к свойствам контролов, расположенных внутри композитного контрола. В частности, нужно обеспечить возможность задания значений свойств Text метки и строки ввода.

Для решения поставленной задачи существует несколько путей. Первый вариант – расширение области видимости контролов контейнера. По умолчанию в композитном контроле вложенные контролы имеют область видимости private и, соответственно, недоступны снаружи.

Изменив область видимости на public, мы делаем возможным доступ к контролам. Описанный способ имеет один серьезный недостаток – так как label1 и textBox1 объявлены как обычные переменные, а не свойства, то о визуальном редактировании их свойств придется забыть, и вводить код установки нужных значений свойств вложенных контролов вручную.

Чтобы обеспечить возможность визуального редактирования, необходимо объявить данные контролы свойствами композитного контрола, доступными только для чтения.

Обратите внимание, что у свойств имеется атрибут DesignerSerializationVisibility со значением, равным DesignerSerializationVisibility.Content. Если не задавать этого атрибута, установленные у textbox и label свойства не будут сериализоваться формой.

Заключение

В данной статье была кратко рассмотрена иерархия классов WinForms-контролов. 🙁 Мы постарались кратко осветить наиболее важные с точки зрения разработчиков контролов классы иерархии. При разработке собственных компонентов трудно переоценить понимание иерархии классов используемой объектной библиотеки, поэтому если после прочтения данной статьи в голове читателя отложилось четкое понимание иерархии контролов WinForms, то мы считаем, что цель написания данной статьи достигнута. Мы преднамеренно не останавливались подробно на побочных аспектах рассмотренных классов.

В дальнейших статьях планируется рассмотреть иерархию классов WebForms, поведение контролов на этапе проектирования, а также затронуть другие актуальные вопросы создания элементов управления в .NET.

Copyright © 1994-2016 ООО «К-Пресс»

Читайте также:  Windows user name format
Оцените статью