Иллюстрированный самоучитель по Architecture .NET
Иерархия Windows Forms (Формы Windows)
К сожалению, конструктор форм (Forms Designer) не поддерживается в C++. Тем не менее, вы можете использовать конструктор форм (Forms Designer) в С#, и потом перенести полученный с помощью С# код графического интерфейса пользователя в программу на C++. Для переноса графического интерфейса пользователя в программу на C++ необходимы дополнительные усилия, и, в большинстве случаев, такой перенос особой пользы не дает. Как правило, C++ не используют для разработки пользовательских графических интерфейсов, вместо этого применяется подход смешения языков, в котором для создания пользовательского интерфейса используется С#, а в других аспектах разработки проекта из разных соображений используется C++.
Поскольку вам, скорее всего, придется часто создавать графический интерфейс пользователя для многих приложений, в этой паве мы преследуем две цели. Во-первых, мы хотим научить вас совместно использовать код на С# и C++. Даже если вы в основном программируете на C++, стоит ознакомиться с С# и конструктором форм (Forms Designer), – у вас появится возможность использовать те мощные инструментальные программные средства, которые не поддерживаются в C++. Во-вторых, мы приведем в пример один из немногих случаев, когда перенос кода графического интерфейса пользователя из С# в программу на C++ является целесообразным. В главе представлено несколько пар примеров кода графических пользовательских интерфейсов до и после переноса.
Ключевым средством взаимодействия пользователя с компьютером является графический пользовательский интерфейс (Graphical User Interface, GUI). Из этой главы вы узнаете, как создавать графический пользовательский интерфейс с помощью классов Windows Forms (Формы Windows), которые находятся в NET Framework. На практике программирование Windows-приложений предполагает экстенсивное использование различных инструментальных средств и мастеров, которые намного упрощают этот процесс. Однако все указанные средства автоматизации заслоняют то, что лежит в основе создания графического пользовательского интерфейса. Поэтому сначала мы рассмотрим основы создания графических пользовательских интерфейсов. Иными словами, мы научимся создавать простые приложения Windows с самого начала, пользуясь только комплексом инструментальных средств разработки программ NET Framework SDK.
Это значит, что вначале мы будем создавать простые приложения Windows без применения каких-либо специальных сервисных программ. Будут рассмотрены основы рисования с помощью Windows Forms (Формы Windows) с применением шрифтов и кистей, а также необходимые обработчики событий. Мы объясним принципы обработки событий в Windows Forms (Формы Windows) и реализуем обработчики событий мыши. С помощью Windows Forms (Формы Windows) мы также реализуем меню и соответствующие обработчики событий.
Кроме того, мы рассмотрим управляющие элементы, а после этого изучим среду Visual Studio .NET, посредством которой можно без труда создать простой графический пользовательский интерфейс на С#. С помощью конструктора форм (Forms Designer) добавим в форму управляющие элементы, создадим меню, добавим обработчики событий и другие полезные функциональные возможности. При желании полученный в результате проект на С# можно потом перенести на C++. В заключение будут рассмотрены диалоговые окна и такой элемент управления, как список.
Windows Forms (Формы Windows) – это та часть каркаса .NET Framework, которая поддерживает создание приложений со стандартным графическим пользовательским интерфейсом (GUI) на платформе Windows. Среди классов Windows Forms (Формы Windows) есть обширный набор классов для создания сложных графических пользовательских интерфейсов. Эти классы можно использовать в приложениях, написанных на любом языке .NET.
Как правило, ваше приложение будет содержать главное окно, которое реализовано с помощью некоторого класса MyForm, производного от класса Form (Форма). На рис 6.1 изображено, какое место ваш класс MyForm занимает в иерархии классов Windows Forms (Формы Windows).
Рис. 6.1. Упрощенная схема иерархии классов Windows Forms (Формы Windows)
Windows forms иерархия классов
Иерархия классов
Ниже показан базовый обзор некоторых ключевых ветвей иерархии классов. Важно отметить, что основные пространства имен WPF начинаются в System.Windows (например, System.Windows, System.Windows.Controls и System.Windows.Media). Единственным исключением являются пространства имен, начинающиеся с System.Windows.Forms, которые относятся к инструментам Windows Forms.
Приложения WPF используют знакомую однопоточную модель (single-thread affinity — STA), а это означает, что весь пользовательский интерфейс принадлежит единственному потоку. Взаимодействовать с элементами пользовательского интерфейса из других потоков небезопасно. Чтобы содействовать работе этой модели, каждое WPF-приложение управляется диспетчером, координирующим сообщения (появляющиеся в результате клавиатурного ввода, перемещений курсора мыши и таких процессов платформы, как компоновка). Будучи унаследованным от DispatcherObject, каждый элемент пользовательского интерфейса может удостовериться, выполняется ли код в правильном потоке, и обратиться к диспетчеру, чтобы направить код в поток пользовательского интерфейса.
Этот тип включает одно свойство, представляющее интерес — Dispatcher, которое возвращает ассоциированный объект System.Windows.Threading.Dispatcher. Класс Dispatcher — это точка входа в очередь событий приложения WPF, предоставляющая базовые конструкции для работы с параллелизмом и многопоточностью. По большому счету, это низкоуровневый класс, который в большинстве приложений WPF может быть проигнорирован.
System.Windows.DependencyObject
В WPF центральный путь взаимодействия с экранными элементами пролегает через свойства. На ранней стадии цикла проектирования архитекторы WPF решили создать более мощную модель свойств, которая положена в основу таких средств, как уведомления об изменениях, наследуемые значения по умолчанию и более экономичное хранилище свойств. Конечным результатом стало средство свойств зависимости (dependency property). За счет наследования от DependencyObject, классы WPF получают поддержку свойств зависимости.
Базовый класс DependencyObject предоставляет два ключевых метода для всех производных типов: GetValue() и SetValue(). С помощью этих членов можно устанавливать само свойство. Другие части инфраструктуры позволяют “регистрировать” тех, кто может использовать свойства зависимости или присоединяемые свойства.
Хотя свойства зависимости — это ключевой аспект разработки WPF, большую часть времени их детали скрыты от глаз.
System.Windows.Media.Visual
Каждый элемент, появляющийся в WPF, в основе своей является Visual. Класс Visual можно воспринимать как единственный объект рисования, инкапсулирующий в себе инструкции рисования, дополнительные подробности рисования (наподобие отсечения, прозрачности и настроек трансформации) и базовую функциональность (вроде проверки попадания). Класс Visual также обеспечивает связь между управляемыми библиотеками WPF и сборкой milcore.dll, которая визуализирует отображение. Любой класс, унаследованный от Visual, обладает способностью отображаться в окне. Если вы предпочитаете создавать свой пользовательский интерфейс с применением легковесного API-интерфейса, не обладающего высокоуровневыми средствами WPF, то можете программировать непосредственно с использованием объектов Visual.
Применение типа Visual (и его потомков вроде DrawingVisual) обеспечивает наиболее легковесный способ визуализации графических данных, но также подразумевает участие большого объема управляемого кода для обеспечения работы всех необходимых служб. System.Windows.UIElement
Класс UIElement добавляет поддержку таких сущностей WPF, как компоновка (layout), ввод (input), фокус (focus) и события (events) — все, что команда разработчиков WPF называет аббревиатурой LIFE. Например, именно здесь определен двухшаговый процесс измерения и организации компоновки. Здесь же щелчки кнопками мыши и нажатия клавиш трансформируются в более удобные события, такие как MouseEnter. Как и со свойствами, WPF реализует расширенную систему передачи событий, именуемую маршрутизируемыми событиями (routed events).
System.Windows.FrameworkElement
Класс FrameworkElement — конечный пункт в центральном дереве наследования WPF. Он реализует некоторые члены, которые просто определены в UIElement. Например, UIElement устанавливает фундамент для системы компоновки WPF, но FrameworkElement включает ключевые свойства (вроде HorizontalAlignment и Margin), которые поддерживают его. UIElement также добавляет поддержку привязки данных, анимации и стилей — все они являются центральными средствами.
System.Windows.Shapes.Shape
От этого класса наследуются базовые фигуры, такие как Rectangle, Polygon, Ellipse, Line и Path. Эти фигуры могут использоваться наряду с более традиционными графическими элементами Windows вроде кнопок и текстовых полей.
System.Windows.Controls.Control
Элемент управления (control) — это элемент, который может взаимодействовать с пользователем. К нему очевидным образом относятся такие классы, как TextBox, Button и ListBox. Класс Control добавляет дополнительные свойства для установки шрифта, а также цветов переднего плана и фона. Но наиболее интересная деталь, которую он предоставляет — это поддержка шаблонов, которая позволяет заменять стандартный внешний вид элемента управления собственным рисованием.
Control, так же, определяет свойства для установки размеров элемента управления, прозрачности, порядка обхода по нажатию клавиши , дисплейного курсора, цвета фона и т.д.
System.Windows.Controls.ContentControl
Это базовый класс для всех элементов управления, которые имеют отдельный фрагмент содержимого. Сюда относится все — от скромной метки Label до окна Window. Наиболее впечатляющая часть этой модели заключается в том, что единственный фрагмент содержимого может быть чем угодно — от обычной строки до панели компоновки, содержащей комбинацию других фигур и элементов управления.
Например, когда речь идет о типичном элементе управления “кнопка”, то обычно предполагается, что его содержимым будет базовый строковый литерал (ОК, Cancel, Abort и т.п.). В случае использования XAML для описания элемента управления WPF, и значение, которое необходимо присвоить свойству Content, может быть выражено в виде простой строки, можете установить свойство Content внутри открывающего определения элемента.
Содержимое может быть любым. Например, предположим, что нужна “кнопка”, которая содержит в себе нечто более интересное, чем простая строка, возможно, специальную графику или текст. На других платформах построения пользовательских интерфейсов, таких как Windows Forms, пришлось бы строить специальный элемент управления, что потребовало бы написания значительного объема кода и сопровождения нового класса. С моделью содержимого WPF это не требуется.
Когда в свойстве Content должно быть установлено значение, которое не может быть выражено простым массивом символов, его нельзя присвоить с использованием атрибута в открывающем определении элемента управления. Вместо этого понадобится определить данные содержимого неявно, внутри контекста элемента.
System.Windows.Controls.ItemsControl
Это базовый класс для всех элементов управления, которые отображают коллекцию каких-то единиц информации, вроде ListBox и TreeView. Списочный элемент управления замечательно гибок; например, используя встроенные средства класса ItemsControl, можно трансформировать обычный ListBox в список переключателей, список флажков, упорядоченный набор картинок или комбинацию совершенно разных элементов по своему выбору. Фактически в WPF все меню, панели инструментов и линейки состояния на самом деле являются специализированными списками и классами.
System.Windows.Controls.Panel
Это базовый класс для всех контейнеров компоновки — элементов, которые содержат в себе один или более дочерних элементов и упорядочивают их в соответствии с определенными правилами компоновки. Эти контейнеры образуют фундамент системы компоновки WPF, и их использование — ключ к упорядочиванию содержимого наиболее привлекательным и гибким способом.
Введение в Windows Forms
Для создания графических интерфейсов с помощью платформы .NET применяются разные технологии – Window Forms, WPF, приложения для магазина Windows Store (для ОС Windows 8/8.1/10). Однако наиболее простой и удобной платформой до сих пор остается Window Forms или формы. Данное руководство ставит своей целью дать понимание принципов создания графических интерфейсов с помощью технологии WinForms и работы основных элементов управления.
Создание графического приложения
Для создания графического проекта нам потребуется среда разработки Visual Studio. Поскольку наиболее распространенная пока версия Visual Studio 2013, то для данного руководства я буду использовать бесплатную версию данной среды Visual Studio Community 2013 которую можно найти на странице https://www.visualstudio.com/en-us/products/visual-studio-community-vs.aspx.
После установки среды и всех ее компонентов, запустим Visual Studio и создадим проект графического приложения. Для этого в меню выберем пункт File (Файл) и в подменю выберем New – > Project (Создать – > Проект). После этого перед нами откроется диалоговое окно создания нового проекта:
В левой колонке выберем Windows Desktop , а в центральной части среди типов проектов – тип Windows Forms Application и дадим ему какое-нибудь имя в поле внизу. Например, назовем его HelloApp. После этого нажимаем OK.
После этого Visual Studio откроет наш проект с созданными по умолчанию файлами:
Большую часть пространства Visual Studio занимает графический дизайнер, который содержит форму будущего приложения. Пока она пуста и имеет только заголовок Form1. Справа находится окно файлов решения/проекта – Solution Explorer (Обозреватель решений). Там и находятся все связанные с нашим приложением файлы, в том числе файлы формы Form1.cs.
Внизу справа находится окно свойств – Properties. Так как у меня в данный момент выбрана форма как элемент управления, то в этом поле отображаются свойства, связанные с формой.
Теперь найдем в этом окне свойство формы Text и изменим его значение на любое другое:
Таким образом мы поменяли заголовок формы. Теперь перенесем на поле какой-нибудь элемент управления, например, кнопку. Для этого найдем в левой части Visual Studio вкладку Toolbox (Панель инструментов) . Нажмем на эту вкладку, и у нас откроется панель с элементами, откуда мы можем с помощью мыши перенести на форму любой элемент:
Найдем среди элементов кнопку и, захватив ее указателем мыши, перенесем на форму:
Это визуальная часть. Теперь приступим к самому программированию. Добавим простейший код на языке C#, который бы выводил сообщение по нажатию кнопки. Для этого мы должны перейти в файл кода, который связан с этой формой. Если у нас не открыт файл кода, мы можем нажать на форму правой кнопкой мыши и в появившемся меню выбрать View Code (Посмотреть файл кода):
Однако воспользуемся другим способом, чтобы не писать много лишнего кода. Наведем указатель мыши на кнопку и щелкнем по ней двойным щелчком. Мы автоматически попадаем в файл кода Form1.cs, который выглядит так:
Добавим вывод сообщения по нажатию кнопки, изменив код следующим образом:
Запуск приложения
Чтобы запустить приложение в режиме отладки, нажмем на клавишу F5 или на зеленую стрелочку на панели Visual Studio. После этого запустится наша форма с одинокой кнопкой. И если мы нажмем на кнопку на форме, то нам будет отображено сообщение с приветствием.
После запуска приложения студия компилирует его в файл с расширением exe. Найти данный файл можно, зайдя в папку проекта и далее в каталог bin/Debug или bin/Release
Рассмотрев вкратце создание проекта графического приложения, мы можем перейти к обзору основных компонентов и начнем мы с форм.
Иллюстрированный самоучитель по Architecture .NET
Иерархия Windows Forms (Формы Windows)
К сожалению, конструктор форм (Forms Designer) не поддерживается в C++. Тем не менее, вы можете использовать конструктор форм (Forms Designer) в С#, и потом перенести полученный с помощью С# код графического интерфейса пользователя в программу на C++. Для переноса графического интерфейса пользователя в программу на C++ необходимы дополнительные усилия, и, в большинстве случаев, такой перенос особой пользы не дает. Как правило, C++ не используют для разработки пользовательских графических интерфейсов, вместо этого применяется подход смешения языков, в котором для создания пользовательского интерфейса используется С#, а в других аспектах разработки проекта из разных соображений используется C++.
Поскольку вам, скорее всего, придется часто создавать графический интерфейс пользователя для многих приложений, в этой паве мы преследуем две цели. Во-первых, мы хотим научить вас совместно использовать код на С# и C++. Даже если вы в основном программируете на C++, стоит ознакомиться с С# и конструктором форм (Forms Designer), – у вас появится возможность использовать те мощные инструментальные программные средства, которые не поддерживаются в C++. Во-вторых, мы приведем в пример один из немногих случаев, когда перенос кода графического интерфейса пользователя из С# в программу на C++ является целесообразным. В главе представлено несколько пар примеров кода графических пользовательских интерфейсов до и после переноса.
Ключевым средством взаимодействия пользователя с компьютером является графический пользовательский интерфейс (Graphical User Interface, GUI). Из этой главы вы узнаете, как создавать графический пользовательский интерфейс с помощью классов Windows Forms (Формы Windows), которые находятся в NET Framework. На практике программирование Windows-приложений предполагает экстенсивное использование различных инструментальных средств и мастеров, которые намного упрощают этот процесс. Однако все указанные средства автоматизации заслоняют то, что лежит в основе создания графического пользовательского интерфейса. Поэтому сначала мы рассмотрим основы создания графических пользовательских интерфейсов. Иными словами, мы научимся создавать простые приложения Windows с самого начала, пользуясь только комплексом инструментальных средств разработки программ NET Framework SDK.
Это значит, что вначале мы будем создавать простые приложения Windows без применения каких-либо специальных сервисных программ. Будут рассмотрены основы рисования с помощью Windows Forms (Формы Windows) с применением шрифтов и кистей, а также необходимые обработчики событий. Мы объясним принципы обработки событий в Windows Forms (Формы Windows) и реализуем обработчики событий мыши. С помощью Windows Forms (Формы Windows) мы также реализуем меню и соответствующие обработчики событий.
Кроме того, мы рассмотрим управляющие элементы, а после этого изучим среду Visual Studio .NET, посредством которой можно без труда создать простой графический пользовательский интерфейс на С#. С помощью конструктора форм (Forms Designer) добавим в форму управляющие элементы, создадим меню, добавим обработчики событий и другие полезные функциональные возможности. При желании полученный в результате проект на С# можно потом перенести на C++. В заключение будут рассмотрены диалоговые окна и такой элемент управления, как список.
Windows Forms (Формы Windows) – это та часть каркаса .NET Framework, которая поддерживает создание приложений со стандартным графическим пользовательским интерфейсом (GUI) на платформе Windows. Среди классов Windows Forms (Формы Windows) есть обширный набор классов для создания сложных графических пользовательских интерфейсов. Эти классы можно использовать в приложениях, написанных на любом языке .NET.
Как правило, ваше приложение будет содержать главное окно, которое реализовано с помощью некоторого класса MyForm, производного от класса Form (Форма). На рис 6.1 изображено, какое место ваш класс MyForm занимает в иерархии классов Windows Forms (Формы Windows).
Рис. 6.1. Упрощенная схема иерархии классов Windows Forms (Формы Windows)