#helpc#windowsforms — Что можно использовать


Содержание

Windows Forms: Современная модель программирования для создания GUI приложений

Чтобы создать GUI приложения в Microsoft .NET нужно использовать Windows Forms. Windows Forms — новый стиль построения приложения на базе классов .NET Framework class library. Они имеют собственную модель программирования, которая более совершеннее, чем модели, основанные на Win32 API или MFC, и они выполняются в управляемой среде .NET Common Language Runtime (CLR). Эта статья дает представление о том, что такое Windows Forms, рассматривая ее от модели программирования до Microsoft Intermediate Language и JIT-транслятора.

Вы уже много слышали, что Microsoft .NET — новая платформа, которая основана на Windows. Это целая новая парадигма программирования, которая изменит путь, которым вы сейчас думаете о написании программ для Windows. Она реализована на библиотеке классов .NET Framework class library и содержит более единую модель программирования, улучшенную защиту и более богатые возможности для написания полнофункциональных веб-приложений. И это только начало.

Windows Forms — одна из наиболее интересных возможностей Microsoft .NET. Если вы знакомы с MFC (или Windows API), то Windows Forms хорошее начало для работы с .NET Framework class library, потому что она позволяет писать традиционные GUI приложения с окнами, формами и т.п. вещами. Однажды, начав работать с Windows Forms вы сможете быстро понять .NET Framework.

Главная выгода от написания Windows-приложений с использованием Windows Forms — это то, что Windows Forms гомогенизируют (создают более однородную (гомогенную) структуру) программную модель и устраняют многие ошибки и противоречия от использования Windows API. Например, каждый опытный программист под Windows знает, что некоторые стили окна могут применяться только к окну, когда оно уже создано. Windows Forms в значительной степени устраняют такое противоречие. Если вы хотите существующему окну задать стиль, который может быть присвоен только в момент создания окна, то Windows Forms спокойно уничтожит окно и вновь создаст его с указанным стилем. Кроме того, .NET Framework class library намного более богаче, чем Windows API, и когда вы будете писать приложения, используя Windows Forms, вы получите в распоряжение больше возможностей. Написание приложения с использованием Windows Forms потребует меньшего количества кода, чем приложения, которые используют Windows API или MFC.

Другая выгода от Windows Forms — вы используете тот же самый API, независимо от языка программирования, который вы выбрали. В прошлом, выбор языка программирования управлял выбором API. Если вы программировали в Visual Basic, вы использовали один API (реализованный на языке Visual Basic), в то время как программисты C использовали Win32 API, а программисты C++, вообще говоря, использовали MFC. MFC-программисту было трудно переключиться на Visual Basic и наоборот. Но теперь такого больше нет. Все приложения, которые используют Windows Forms, используют один API из .NET Framework class library. Знание одного API достаточно позволит программисту писать приложения фактически на любом языке, который он выберет.

Windows Forms ни как не меньше, чем современная модель программирования для GUI приложений. В отличие от модели программирования Win32, в которой многое идет еще от Windows 1.0, новая модель была разработана с учетом всех современных требований. Цель этой статьи состоит в том, чтобы познакомить читателя с моделью программирования Windows Forms. Чтобы компилировать и выполнять примеры кода, приведенного далее, на вашем компьютере должнен быть установлен пакет Microsoft .NET Framework SDK (.NET Framework SDK Beta 1 доступен на сайте Microsoft).

Модель программирования Windows Forms

В Windows Forms термин «форма» — синоним окна верхнего уровня. Главное окно приложения — форма. Любые другие окна верхнего уровня, которые имеет приложение — также формы. Окна диалога также считаются формами. Несмотря на название, приложения, использующие Windows Forms, не выглядят как формы. Подобно традиционным Windows-приложениям приложения осуществляют полный контроль над событиями в собственных окнах.

Программисты видят Microsoft .NET через линзу .NET Framework class library. Представьте MFC на порядок больше и вы получите точную картину о ширине и глубине .NET Framework class library. Чтобы облегчить противоречия в обозначениях и придать организацию многим сотням классов, .NET Framework class library разбита на иерархические разделы по именам. Корневой раздел, System, определяет фундаментальные типы данных, используемые всеми приложениями .NET.

Приложения, использующие Windows Forms используют классы System.WinForms. Этот раздел включает такие классы, как Form, который моделирует поведение окон или форм; Menu, который представляет меню; Clipboard, который дает возможность приложениям Windows Forms использовать буфер обмена. Он также содержит многочисленные классы, предоставляющие средства управления, например: Button, TextBox, ListView, MonthCalendar и т.д. Эти классы могут быть включены в приложение либо с использованием только имени класса, либо с использованием полного имени, например: System.WinForms.Button.

В основе почти каждого приложения, написанного с применением Windows Forms, — производный класс от System.WinForms.Form. Образец этого класса представляет главное окно приложения. System.WinForms.Form имеет множество свойств и методов, которые имеют богатый программный интерфейс к формам. Хотите знать размеры клиентской области формы? В Windows вы вызвали бы функцию API GetClientRect. В Windows Forms нужно использовать свойства ClientRectangle или ClientSize.

Приложения, основанные на Windows Forms, которые используют кнопки, списки и другие типы компонентов Windows, используют классы управления System.WinForms, значительно упрощающие программирование управления. Хотите создать стилизованную кнопку с изображением в виде фона? Нет проблем. Включите требуемое изображение в объект System.Drawing.Bitmap и назначьте его свойству кнопки BackgroundImage. Как насчет управления цветом? Вы когда-либо пробовали настраивать цвет фона текстового поля? В Windows Forms это просто: нужно просто присвоить цвет свойству BackColor, все отстальное система сделает сама.

Другой важный «строительный» блок приложения, который использует Windows Forms — класс System.WinForms по имени Application. Этот класс содержит статический метод Run, который загружает приложение и отображает окно.

Вы скажете: если приложения, которые являются Windows Forms, не обрабатывают сообщения, как они отвечают на пользовательский ввод или знают когда рисовать? Много классов имеют виртуальные методы, которые можно переопределить. Например, System.WinForms.Form содержит виртуальный метод OnPaint, который вызывается когда клиентская область формы нуждается в обновлении. OnPaint — один из многих виртуальных методов, который можно переопределить в производном классе для формирования интерактивных форм.

Другая важная грань модели программирования Windows Forms — механизм, который формы используют для ответа на ввод в меню, средств управления и других элементов GUI приложения. Традиционные Windows-приложения обрабатывают сообщения WM_COMMAND и WM_NOTIFY используя события процесса Windows Forms. В C# и на других языках, которые поддерживают .NET Common Language Runtime (CLR), события — члены типа первого класса наравне с методами, полями и свойствами. Фактически все управляющие классы (control classes) Windows Forms (а также и многие неуправляющие классы) создают события. Например, кнопка (экземпляр System.WinForms.Button) после нажатия создает событие Click. Форма, которая должна ответить на нажатие кнопки может использовать следующий код, чтобы соединить кнопку на обработчиком события Click:

EventHandler — специальный обработчик событий, который выполняет метод OnButtonClicked когда MyButton создает событие Click. Первый параметр OnButtonClicked идентифицирует объект, который вызвал событие. Второй параметр в основном бессмысленен для события Click, но используется некоторым другие типами событий, чтобы передать дополнительную информацию.

Приложение «Hello World» с Windows Forms

Самый простой способ начать изучение новой платформы — создание приложения «Hello World». В Листинге 1 показана версия, созданная при помощи Windows Forms. Все примеры в этой статье написаны на C#, но вы можете писать приложения Windows Forms на любом языке, для которого есть компилятор .NET. Сегодня это: C#, Visual Basic, JScript и C++.

Начнем сначала. Слово «using» вверху файла позволяют сослаться на классы в пакетах System, System.WinForms и System.Drawing. Например,

В приложении, использующем Windows Forms, каждое окно — или форма — представлено экземпляром класса, производного от System.WinForms.Form (Листинг 1 — класс MyForm). Конструктор MyForm устанавливает текст заголовка формы «Windows Forms Demo» используя свойство Text. Text — одно из более чем 100 свойств, которые форма наследует от System.WinForms.Form, но пока единственное, в котором вы нуждаетесь.

Как вы знаете, окна получают сообщения WM_PAINT и большинство перерисовок экрана выполнено в ответ на эти сообщения. В Windows Forms эквивалент сообщения WM_PAINT — виртуальный метод по имени OnPaint. Производный класс формы может переопределить этот метод в случае надобности выполнять собственную перерисовку в ответ на сообщения WM_PAINT.

Обратите внимание на ключевое слово в Листинге 1, которое компилятор C# интерпретирует как подтверждение, что вы хотите переопределить виртуальный метод, унаследованный от базового класса. Перопределенный OnPaint записывает «Hello, world» в клиентской области формы. OnPaint вызывает объект PaintEventArgs (System.WinForms.PaintEventArgs), который содержит свойства Graphics и ClipRectangle. Свойство Graphics ссылается к объекту Graphics (System.Drawing.Graphics), который является эквивалентом контекста устройства (device context) в Windows Forms. ClipRectangle производное объекта Rectangle (System.Drawing.Rectangle), который описывает какая часть формы является недопустимой.

Метод OnPaint из MyForm использует Graphics.DrawString, чтобы выполнить вывод на экран. Первый параметр DrawString — непосредственно само сообщение (строка) «Hello, world». Второй — объект Font (System.Drawing.Font), который описывает шрифт для вывода текста. MyForm.OnPaint использует шрифт формы (которой установлен в свойстве Font формы). Третий параметр — Brush (System.Drawing.Brush) — объектное определение цвета текста. Четвертый и заключительный параметр — прямоугольник области, куда требуется вписать текст.

Заключительная часть MyForm — статический метод Main. Main — точка входа в приложение. Каждое приложение .NET должно иметь этот метод. Main может быть объявлен любым из следующих способов:

Параметр args метода Main — строковый массив параметров командной строки (задаваемых при вызове программы). Элемент args[0] хранит первый параметр командной строки, args[1] — второй и т.д. Как правило, в каждом приложении метод Main выполняется только однажды (компилятор Microsoft C# допускает использование ключа /main, указывающего в каком классе содержится метод Main, если приложение имеет несколько классов с методами Main). Main может находиться в любом классе, определенном в приложении.

Отображение нашей формы на экране — простой пример выполнения MyForm и передачи действия Application.Run. Application — другой класс, определенный в System.WinForms. Метод Run создает форму, отображает ее на экране и обрабатывает сообщения к ней. Следующая инструкция в Листинге 1

обрабатывает MyForm и показывает форму.

Сохраните текст программного кода (Листинг 1) в файле Hello.cs и откомпилируйте его. Чтобы это сделать, откройте окно командной строки, перейдите в каталог файла Hello.cs и введите:

Команда csc вызывает компилятор Microsoft C#. «Hello.cs» указывает на файл, который требуется откомпилировать. Ключ «/target:winexe» сообщает компилятору, что нужно создать GUI-приложение для Windows, а «/out:Hello.exe» задает имя файла программы (этот ключ можно опустить, т.к. в данном случае по умолчанию все равно будет создан Hello.exe, т.к. CS-файл назван Hello.cs). Ключи «/reference» указывают ссылки на внешние классы, например, для System.WinForms.Form и System.Drawing.Size. Для краткости допускается заменять «/target» и «/reference» на «/t» и «/r».

Hello.exe не обычный EXE-файл, это .NET-программа, содержащая следующие важные элементы:

  • Microsoft Intermediate Language (MSIL), сгенерированный при помощи C#
  • Метаданные, описывающие типы (классы), определенные в приложении, и типы (например, System.WinForms.Form), на которые ссылается приложение, находящиеся в другом месте (например, в MsCorLib.dll и System.WinForms.dll)
  • Декларация, описывающая требуемые файлы для сборки приложения

В языке .NET, сборка — это коллекция из одного или более файлов, создающих модуль. Наша сборка содержит только один файл — Hello.exe — и этот факт отмечен в декларации внутри выполнимой программы. Декларация физически сохранена как часть метаданных. Каждая управляемая выполнимая программа — это есть любой PE-файл, который содержит MSIL — часть сборки и каждая управляемая выполнимая программа имеет метаданные внутри. Один из файлов в .NET-сборке содержит декларацию идентификации файлов, которые должны быть включены при сборке и общедоступные типы. Компилятор C# производит всю необходимую инфраструктуру.

Теперь когда вы откомпилировали Hello.exe, можете набрать в командной строке:

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

Введение в 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

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

Тема 10. Создание приложений Windows.Forms

Теоретический материал

Визуальное программирование –способ создания программы с помощью графических объектов. Визуальное программирование используется для создания программ с графическим интерфейсом.

Windows.Forms – это набор различных управляемых библиотек, с помощью которых можно выполнить все необходимые для оконного приложения действия (обмен сообщениями с операционной системой, связью с другими компьютерами по сети, обработка событий мыши и клавиатуры и т.д.).

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

Windows Forms – новый стиль построения приложения на базе классов .NET Framework class library. Они выполняются в управляемой среде .NET Common Language Runtime (CLR).

Приложения, использующие Windows Forms используют классы System.WinForms. Этот раздел включает такие классы, как Form, который моделирует поведение окон или форм; Menu, который представляет меню; Clipboard, который дает возможность приложениям Windows Forms использовать буфер обмена. Он также содержит многочисленные классы, предоставляющие средства управления, например: Button, TextBox, ListView, MonthCalendar и т.д. Эти классы могут быть включены в приложение либо с использованием только имени класса, либо с использованием полного имени, например: System.WinForms.Button.

Цукерберг рекомендует:  CSS для потерявшихся позиционирование

Другой важный компонент приложения, который использует Windows Forms – класс System.WinForms по имени Application. Этот класс содержит статический метод Run, который загружает приложение и отображает окно.

Практические задачи

1. Создайте новый проект, в котором по нажатию кнопки появляется надпись «Здравствуйте!».

Создайте новый проект, выберите «Создать проект» / приложение Windows Forms(рис. 85).

Рисунок 85. Создание нового проекта

Введите название проекта и нажмите кнопку ОК.

Рисунок 86. Рабочее окно проекта

Рабочее окно MS Visual Studio(рис. 86) содержит следующие вспомогательные окна:

— окно Toolbox (Панель элементов управления) – элементы управления, которые размещаются на форме.

— окно Solution Explorer (Обозреватель решений): Properties — настройки проекта, Links (Ссылки) – подключенные к проекту библиотеки, а также созданные и подключенные к проекту файлы исходных кодов (с расширением .cs) и подключенные к проекту формы.

— окно Class View (Окно классов) – классы, которые созданы в проекте.

— Окно Properties (Свойства) – параметры любого объекта с панели элементов управления.

Недостающие компоненты можно подключить с помощью вкладки Вид: Вид / Окно свойств, Вид / Панель элементов.

Изменим свойства формы (рис. 87).

Рисунок 87. Свойства формы

Назовем форму «Проект1» вместо Form1. Для этого изменим свойство Text.

Далее разместим на форму элемент label и две кнопки (рис. 88 — 90).

Рисунок 88. Добавление элементов

Рисунок 89. Итоговый вид формы

Изменим свойства у данных элементов. Для этого необходимо выделить нужный элемент, щелкнув по нему один раз левой кнопкой мыши и зайти в редактор свойств.

Рисунок 90. Итоговый вид формы после изменения свойств объектов

Дважды щелкнем по кнопке «Показать» и откроем редактор кода.

Запишем следующий код для элемента button1 (рис. 91).

Рисунок 91. Код для объекта button1

Откроем форму и у элемента Label1 изменим свойство visible на false (рис. 92).

Рисунок 92. Изменение свойств объекта label1


Для второй кнопки напишем код, который позволяет закрывать форму (рис. 93).

Рисунок 93. Код для объекта button2

2. Создадим проект, для перевода n метров в километры.

Заготовим форму проекта (рис. 94).

Рисунок 94. Форма

Изменим свойства элементов и приведем форму к виду, представленному на рисунке 96. У элемента label2 оставим пустым значение свойства text (рис. 95).

Рисунок 95. Свойства объекта label2

Рисунок 96. Итоговый вид формы

Напишем код для кнопки «ОК» (рис. 97).

Рисунок 97. Код для кнопки «ОК»

Проверьте работоспособность проекта.

3. Создать калькулятор для расчета стоимости фотографий, в зависимости от их размера (рис. 98).

Рисунок 98. Форма

Для задания значения размера фотографии воспользуйтесь компонентом RadioButton. Для вывода значений будем использовать компонент label2 (рис. 99).

Рисунок 99. Добавление элемента RadioButton

Введите программный код для инициализации компонентов и для кнопки ОК (рис. 100).

Рисунок 100. Код для кнопки «ОК»

4. Рассчитать стоимость автомобиля, в зависимости от комплектации. На форму необходимо вынести компонент CheckBox (рисунок 101).

Рисунок 101. Добавление элемента CheckBox

Для добавление графического файла необходимо вынести на форму компонент PictureBox. Затем у данного компонента выбрать свойство Image и загрузить изображение: локальный ресурс / импорт (рис. 102).

Рисунок 102. Добавление изображения на форму

Для отображения рисунка в полный размер у свойства рисунка выбрать StretchImage (рис. 103).

Рисунок 103. Отображение изображения в полном размере

Рисунок 104. Итоговый вид формы

Программный код представлен на рисунке 105.

Рисунок 105. Код программы

1. Вычислить стоимость жалюзи, в зависимости от материала: пластик, текстиль, соломка (рис. 106, 107). Для задания типа материала использовать компонент ComboBox.

Рисунок 106. Форма

Рисунок 107. Код для кнопки «ОК»

Вопросы для контроля знаний

1. В чем особенность визуального программирования?

2. Как связаны визуальное и объектно-ориентированное программирование?

3. Какие языки реализуют возможности визуального программирования?

4. В чем особенность Windows Forms?

5. Какие проекты можно создавать с помощью языков визуального программирования?

6. Какие классы можно использовать в System.WinForms?

Задачи для самостоятельного решения

1. Создать калькулятор для перевода n рублей в евро, кроны и Йены.

2. Создать калькулятор для расчета стоимости покупки в магазине с учетом скидки. На форме должен быть представлен ассортимент товаров. Клиент может выбрать товары в разном количестве.

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

Последнее изменение этой страницы: 2020-01-26; Нарушение авторского права страницы

Введение в Windows Forms — пишем первую программу

В данной статье будет рассказано о том как написать простой обработчик событий на C++ для приложения Windows Forms, работающего под управления .NET Framework. Мы создадим простейшую Windows программу, которая вычисляет факториал целого числа. Для написания данной программы Вам понадобится Visual Studio 2008 Express Edition или Professional.


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

Откроем Visual Studio, далее жмем Файл→Создать→Проект, далее выбираем пункт CLR и отмечаем Приложение Windows Forms, даем имя проекта, к примеру factr и жмем Ok.

После того как мы создали проект, должна появиться пустая форма, которая должна выглядеть примерно так:

Справа должна появиться панель элементов, если ее нет, то можно включить ее в меню Вид→Панель Элементов или нажатием горячих клавиш — Ctrl + Alt + X.

На ней расположены различные элементы для вставки в форму, нам понадобятся только элементы Button (Кнопка), Label (Надпись) и TextBox (Текстовое поле). Перетащите на форму три элемента Label, Два элемента TextBox, и одну кнопку (Button), расставьте элементы примерно так:

Теперь нам нужно будет изменить текст надписей для элементов Label и Button и Задать подходящие имена классов для элементов TextBox. Для этого Выделите элемент label1, перейдите в Панель свойств, (обычно она находится под Панелью элементов, если панель выключена, включите ее в меню Вид -> Диспетчер свойств.) и задайте для данного элемента значение атрибута Text как показано на рисунке.

Задайте атрибут Text для всех элементов Label и Кнопки Button аналогичным образом. Наша форма должна принять примерно следующий вид:

Я сделал кнопку развернуть неактивной, так как изменение размеров данной формы испортит ее внешний вид, Вы также можете это сделать, щелкнув левой кнопкой мыши на пустом месте формы и в Панели свойств задать для атрибута MaximizeBox параметр False.

Теперь задайте для текстовых полей (TextBox) Атрибуты Name в Панели Свойств – для первого поля это будет num1, а для второго, соответственно num2. Тем самым мы изменили имена классов для полей TextBox, чуть позднее Вы поймете зачем.

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

Первым делом нужно добавить заголовочный файл fact.h в проект, для этого щелкаем правой кнопкой мыши в Обозревателе решений на папке Заголовочные файлы, далее меню Добавить -> Создать Элемент, вписываем название файла – fact.h и нажимаем Добавить. В данном файле будет содержаться прототип функции для вычисления факториала. Добавляем туда следующий исходный код.

Далее подключаем этот файл к проекту с помощью директивы #include – Открываем файл factr.cpp и добавляем после строчки #include «stdafx.h» следующий код.

Теперь наш заголовочный файл подключен к проекту, далее аналогичным образом создаем файл исходного кода fact.cpp в проект.

В него добавляем саму функцию вычисления факториала целого числа.

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

Открываем файл Form.h, в нем мы видим визуальное представление нашей формы. Щелкаем двойным щелчком на кнопке Button и переходим к исходному коду.

После фигурной скобки ставим абзац и приступаем к кодированию. Любой набор символов, которые мы вводим с клавиатуры в текстовое поле программы является строкой, поэтому нам нужно вытащить значение из текстового поля и привести его к целочисленному типу. Это довольно сложная процедура, но, к счастью в языке C++ уже есть множество функций, выполняющих конвертирование типов данных. Сначала нам необходимо описать и инициализировать переменную, в которой будет храниться значение числа, для которого должен быть вычислен факториал. Добавим в том место, где Вы поставили абзац следующий код:

Эта строка инициализирует переменную, которая хранит в себе число для вычисления его факториала. Далее нам нужно будет произвести вызов нашей функции fact с переменной number в качестве единственного аргумента и занести результат работы функции в новую переменную factor.

И затем преобразовать полученное значение обратно в строку и присвоить его второму текстовому полю.

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

Теперь можно скомпилировать и запустить готовую программу и проверить ее. Помните, что тип double в С++ может хранить число не превышающее !170.

Результат работы программы можно проверить в инженерном калькуляторе Windows.

Обработка событий в Windows Forms

GUI управляется событиями. Приложение выполняет действия в ответ на события, вызванные пользователем, например, на щелчок кнопкой мыши или выбор пункта меню. Например, у каждой формы есть код, обрабатывающий событие MouseDown (Кнопка мыши нажата). В Windows Forms применяется модель обработки событий .NET, в которой делегаты используются для того, чтобы связать события с обрабатывающими их методами. В классах Windows Forms используются групповые делегаты. Групповой делегат содержит список связанных с ним методов. Когда в приложении происходит событие, управляющий элемент возбуждает событие, вызвав делегат для этого события. Потом делегат вызывает связанные с ним методы. Для того чтобы добавить делегат к событию используется перегруженный оператор +=. Например:

this.MouseClick += new MouseEventHandler(this.Form1_MouseClick);

Объявление обработчика для этого события:

private void Form1_MouseClick(object sender, MouseEventArgs e)

В качестве параметра обработчик событий получает объект класса МоuseEventArgs (производный от класса EventArgs). Свойства этого объекта доступны только для чтения и содержат информацию, связанную с данным событием.

· Button (Кнопка) определяет, какая кнопка была нажата,

· Clicks (Щелчки) определяет, сколько раз была нажата и отпущена кнопка,

· Свойство Delta (Дельта) является счетчиком оборотов колесика мыши;

· X и Y — координаты точки, в которой находился указатель в момент нажатия кнопки мыши

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

//Программа 1: Отображает перемещение приветствия по щелчку мыши.
public partial class Form1 : Form <

Float x, y; // координаты

Brush pStdBrush; // Кисть

Graphics poGraphics;

public Form1() <

InitializeComponent();

x=10;

y=20;

pStdBrush = new SolidBrush(Color.Black);

poGraphics = this.CreateGraphics();

this.Text = «Программа 2»;


this.Show();

poGraphics.DrawString(«Hello, Window Forms», this.Font, pStdBrush, x, y);

private void Form1_MouseClick(object sender, MouseEventArgs e) <

x = (float)e.X; y = (float)e.Y; // координаты точки щелчка мыши

poGraphics.DrawString(«Hello, Window Forms», this.Font, pStdBrush, x, y);

Параметры метода DrawString:

· шрифт (Font— свойство класса Form, которое определяет шрифт, по умолчанию применяемый для вывода текста в форму),

· координаты в пикселях (числа типа float (с плавающей точкой)).

В качестве стандартной кисти используется черная кисть SolidBrush.

Во время инициализации программа связывает метод Form1_MouseClick с событием MouseClick. Этот метод устанавливает координаты текста, х и у, равными координатам точки, в которой находился указатель в момент щелчка.

Не нашли то, что искали? Воспользуйтесь поиском:

Лучшие изречения: При сдаче лабораторной работы, студент делает вид, что все знает; преподаватель делает вид, что верит ему. 9341 — | 7295 — или читать все.

188.64.174.135 © studopedia.ru Не является автором материалов, которые размещены. Но предоставляет возможность бесплатного использования. Есть нарушение авторского права? Напишите нам | Обратная связь.

Отключите adBlock!
и обновите страницу (F5)

очень нужно

#helpc#windowsforms — Что можно использовать?

Система работы с проектами Visual Studio предоставляет значительную поддержку для локализации приложений, работающих с формами Windows Forms. Существуют два способа создания файлов ресурсов при помощи среды разработки Visual Studio.

Файлы ресурсов могут создаваться системой проектов для локализуемых элементов пользовательского интерфейса, таких как текст и изображения в форме. Затем файлы ресурсов будут встраиваться в сопутствующие сборки. Такие ресурсы называются ресурсами форм.

Добавление шаблона файла ресурсов и затем редактирование шаблона с помощью конструктора XML. Второй способ применяется для создания локализуемых строк в диалоговых окнах и сообщениях об ошибках. Затем необходимо написать код для доступа к этим ресурсам. Такие ресурсы называются ресурсами проекта.

В общем случае, ресурсы форм следует использовать для всех ресурсов, относящихся к форме в приложении Windows Forms. Ресурсы проекта следует использовать для всех строк и изображений, которые не основаны на форме, таких как сообщения об ошибках.

Важно придерживаться единообразия и для одного и того же свойства использовать либо ресурсы форм, либо ресурсы проекта. Многие свойства изображений, например свойство Image в PictureBox , позволяют выбрать изображение из ресурсов проекта или импортировать новое изображение как ресурс форм. Если попытаться задать изображение по умолчанию при помощи ресурса проекта, а языковые версии изображения – при помощи ресурсов форм, изображение по умолчанию никогда не будет отображаться.

Данное пошаговое руководство демонстрирует оба процесса в рамках одного проекта приложения Windows.

Также можно преобразовать текстовый файл в файл ресурсов. Дополнительные сведения см. в разделах Resources in Text File Format и Resgen.exe (генератор файлов ресурсов) .

Автоматическая генерация файлов ресурсов средствами Visual Studio

Создайте новое приложение Windows с именем «WindowsApplication1». Дополнительные сведения см. в разделе Практическое руководство. Создание проекта приложения Windows Forms .

В окне Свойства присвойте свойству Localizable формы значение true .

Свойство Language уже имеет значение (По умолчанию) .

Перетащите элемент управления Button с вкладки Windows Forms Области элементов в форму и установите для него значение свойства Text равным Hello World .

Для свойства Language формы задайте значение Немецкий (Германия) .

Задайте для свойства Text кнопки значение Hallo Welt .

Для свойства Language формы задайте значение Французский (Франция) .

Задайте для свойства Text кнопки значение Bonjour le Monde . При необходимости можно изменить размер кнопки для вмещения более длинной строки.

Сохраните результаты и постройте решение.

Нажмите кнопку Показать все файлы в обозревателе решений .

Файл ресурса появится под Form1.cs или Form1.jsl. Form1.resx — это файл ресурсов для языка и региональных параметров по умолчанию, который будет встроен в основную сборку. Form1.de-DE.resx — это файл ресурсов для варианта немецкого языка, принятого в Германии. Form1.fr-FR.resx – это файл ресурсов для варианта французского языка, принятого во Франции.

Кроме того, появятся файлы с именами Form1.de.resx и Form1.fr.resx. Visual Studio автоматически создает эти файлы для обхода ограничения в Visual SourceSafe, запрещающего добавлять в проект новые файлы в ходе операции сохранения. Файлы RESX пусты и не содержат ресурсов.

Нажмите клавишу F5 или выберите в меню Отладка команду Запуск .

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

Примечание

Язык пользовательского интерфейса в Windows зависит от параметра CurrentUICulture . Если в данном экземпляре Windows установлен многоязыковой интерфейс (MUI), можно изменить язык интерфейса в панели управления. Дополнительные сведения см. на странице Многоязыковой пользовательский интерфейс Windows Server 2003, Windows XP и Windows 2000 в Интернете. Если MUI не установлен, можно изменить текущий язык и региональные параметры интерфейса программно, как описано ниже.

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

Настройка языка и региональных параметров интерфейса для просмотра определенных ресурсов

В Редакторе кода добавьте следующий код в начало модуля, перед объявлением Form1:

Добавьте следующий код. В Visual Basic он добавляется в функцию New , до вызова функции InitializeComponent . В Visual C# он добавляется в функцию Form1 , и тоже до вызова функции InitializeComponent .


Сохраните результаты и постройте решение.

Нажмите клавишу F5 или выберите в меню Отладка команду Запуск .

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

Добавление файлов ресурсов в проект вручную и их редактирование

В меню Проект выберите команду Добавить новый элемент .

В поле шаблонов выберите шаблон Файл ресурсов . В поле Имя введите имя файла «WinFormStrings.resx». Файл «WinFormStrings.resx» будет содержать резервные ресурсы на английском языке. Обращение к этим ресурсам будет происходить каждый раз, когда приложение не сможет найти ресурсы, более соответствующие языку и региональным параметрам пользовательского интерфейса.

Файл добавляется в проект в обозревателе решений и автоматически открывается в конструкторе XML в представлении Данные .

В области Таблицы данных выберите данные .

В области Данные щелкните пустую строку, после чего введите strMessage в столбце имя и Hello World в столбце значение .

Значения «type» и «mimetype» для строки указывать не нужно; они предусмотрены для объектов. Описатель типа содержит тип данных сохраняемого объекта. Описатель типа MIME задает базовый тип (base64) сохраняемой двоичной информации, если объект состоит из двоичных данных.

В меню Файл выберите Сохранить WinFormStrings.resx .

Выполните действия 1-5 еще два раза, чтобы создать новые файлы ресурсов с именами WinFormStrings.de-DE.resx и WinFormStrings.fr-FR.resx, со строками ресурсов, указанными в следующей таблице. Файл WinFormStrings.de-DE.resx будет содержать ресурсы, относящиеся к варианту немецкого языка, принятому в Германии. Файл WinFormStrings.fr-FR.resx будет содержать ресурсы, относящиеся к варианту французского языка, принятому во Франции.

Имя файла ресурса

Bonjour le Monde

Доступ к ресурсам, добавленным вручную

В Редакторе кода импортируйте пространство имен System.Resources в начало модуля кода.

В режиме разработки дважды нажмите кнопку, чтобы отобразить код для обработчика соответствующего события Click , и добавьте следующий код. Конструктор ResourceManager имеет два аргумента. Первый — это корневое имя ресурсов, т. е. имя файла ресурсов без указания языка и региональных параметров, а также суффикса .resx. Вторым аргументом является основная сборка.

В этом пошаговом руководстве пространства имен не объявляются, так что первый аргумент конструктора ResourceManager может принимать вид ProjectName.ResourceFileRootName . Однако в реальных приложениях обычно устанавливается свойство DefaultNamespace . В этом случае потребуется объявить диспетчер ресурсов с полным корневым именем файла ресурсов, включая пространство имен. Например, если имя пространства имен – MyCompany.MyApplication.MyComponent , первый аргумент конструктора ResourceManager может быть MyCompany.MyApplication.MyComponent.WinFormStrings .

Примечание

По умолчанию регистр в объекте ResourceManager учитывается. Если требуется поиск без учета регистра, чтобы «TXTWELCOME» возвращал тот же ресурс, что и «txtWelcome», можно установить свойство диспетчера ресурсов IgnoreCase равным true . Однако по соображениям быстродействия лучше всего всегда указывать имена ресурсов в правильном сочетании прописных и строчных букв. Поиск ресурсов без учета регистра может вызвать снижение производительности.

Выполните построение и запустите форму. Щелкните кнопку.

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

Особенности реализации MVP для Windows Forms

Постановка задачи

Придумаем простую задачу — реализовать 3 экрана:
1) экран авторизации;
2) главный экран;
3) модальный экран изменения имени пользователя.
Должно получиться что-то вроде этого:

Немного теории

MVP, как и его родитель, MVC (Model-View-Controller) придуман для удобства разделения бизнес-логики от способа ее отображения.

На просторах интернета можно встретить целое множество реализаций MVP. По способу доставки данных в представление их можно разделить на 3 категории:
— Passive View: View содержит минимальную логику отображения примитивных данных (строки, числа), остальным занимается Presenter;
— Presentation Model: во View могут передаваться не только примитивные данные, но и бизнес-объекты;
— Supervising Controller: View знает о наличии модели и сам забирает из нее данные.

Далее будет рассматриваться модификация Passive View. Опишем основные черты:
— интерфейс Представления (IView), который предоставляет некий контракт для отображения данных;
— Представление — конкретная реализация IView, которая умеет отображать саму себя в конкретном интерфейсе (будь то Windows Forms, WPF или даже консоль) и ничего не знает о том, кто ей управляет. В нашем случае это формы;
— Модель — предоставляет некоторую бизнес-логику (примеры: доступ к базе данных, репозитории, сервисы). Может быть представлена в виде класса или опять же, интерфейса и реализации;
— Представитель содержит ссылку на Представление через интерфейс (IView), управляет им, подписывается на его события, производит простую валидацию (проверку) введенных данных; также содержит ссылку на модель или на ее интерфейс, передавая в нее данные из View и запрашивая обновления.

Какие плюсы нам дает малая связанность классов (использование интерфейсов, событий)?
1. Позволяет относительно свободно менять логику любого компонента, не ломая остального.
2. Большие возможности при unit-тестировании. Поклонники TDD должны быть в восторге.
Начнем!

Как организовать проекты?

Условимся, что решение будет состоять из 4х проектов:
— DomainModel — содержит сервисы и всевозможные репозитории, одним словом — модель;
— Presentation — содержит логику приложения, не зависящую от визуального представления, т.е. все Представители, интерфейсы Представлений и остальные базовые классы;
— UI — Windows Forms приложение, содержит только лишь формы (реализацию интерфейсов Представлений) и логику запуска;
— Tests — unit-тесты.

Что писать в Main()?

Стандартная реализация запуска Windows Forms приложения выглядит так:

Но мы условились, что Представители будут управлять Представлениями, следовательно хотелось бы, чтобы код выглядел как-то так:

Попробуем реализовать первый экран:

Создать форму и реализовать в ней интерфейс ILoginView не составит труда, как и написать реализацию ILoginService. Следует только отметить одну особенность:

Это заклинание позволит нашему приложению запуститься, отобразить форму, а по закрытии формы корректно завершить приложение. Но к этому мы еще вернемся.

А тесты будут?

С момента написания представителя (LoginPresenter), появляется возможность сразу же его от-unit-тестировать, не реализуя ни формы, ни сервисы.
Для написания тестов я использовал библиотеки NUnit и NSubstitute (библиотека создания классов-заглушек по их интерфейсам, mock).

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

Кто и как запустит второй экран с параметром?

Как вы могли заметить, я не написал никакого кода при успешной авторизации. Как же мне запустить второй экран? Первое на ум приходит это:


Но мы условились, что представители ничего не знают о представлениях кроме их интерфейсов. Что же делать?
На помощь приходит паттерн Application Controller (реализован упрощенно), внутри которого содержится IoC-контейнер, знающий, как по интерфейсу получить объект реализации.
Контроллер передается каждому Представителю параметром конструктора (снова DI) и реализует примерно следующие методы:

После небольшого рефакторинга запуск приложения стал выглядеть так:

Пару слов о new ApplicationController(new LightInjectAdapder()) . В качестве IoC-контейнера я использовал библиотеку LightInject, но не напрямую, а через адаптер (паттерн Adapter), чтобы в случае, если понадобится сменить контейнер на другой, я смог написать другой адаптер и не менять логику контроллера. Все используемые методы есть в большинстве IoC-библиотек, сложностей возникнуть не должно.
Реализуем дополнительный интерфейс

Нельзя просто так взять и закрыть форму.

Один из подводных камней связан со строчкой View.Close() , после которой закрывалась первая форма, а вместе с ней и приложение. Дело в том, что Application.Run(Form) запускает стандартный цикл обработки сообщений Windows и рассматривает переданную форму как главную форму приложения. Это выражается в том, что приложение вешает ExitThread на событие Form.Closed , что и вызывает закрытие приложения после закрытия формы.
Обойти данную проблему можно несколькими способами, один из них — использовать другой вариант метода: Application.Run(ApplicationContext) , затем вовремя подменяя свойство ApplicationContext.MainForm . Передача контекста формам реализована с помощью Контроллера приложения, в котором регистрируется объект (instance) ApplicationContext и затем подставляется в конструктор формы (опять DI) во время запуска Представителя. Методы отображения первых двух экранов теперь выглядят так:

Модальное окно

Реализация модального окна не вызывает затруднений. По кнопке «Сменить имя» выполняется Controller.Run (user) . Единственное отличие этой формы от остальных — она не главная, поэтому форме для показа не требуется ApplicationContext:

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

Ну и накрутили. Как теперь ЭТО использовать?

Теперь, когда каркас готов, добавление новой формы сводится к следующим шагам:

  1. Пишем интерфейс Представления, интерфейс Модели (если требуется).
  2. Реализуем Представителя, попутно решив, будем ли мы в него передавать какие-то данные или модель.
  3. [Опционально] Пишем тесты для Представителя, убеждаемся, что все нормально.
  4. [Опционально] Реализуем Модель и тесты для нее.
  5. Накидываем формочки и реализуем интерфейс Представления.

Смена IoC-контейнера на ваш любимый происходит путем реализации простого интерфейса IContainer классом-адаптером.

Забрать демонстрационный проект можно c Github (для сборки необходимо выкачать Nuget-зависимости).

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

Бонус. Хочу еще круче, больше, сложнее!

На этом я остановлюсь, а пытливые умы могут идти дальше:
— улучшение Контроллера приложения (у меня написан немного упрощенный вариант);
— реализация агрегирования событий для обмена информацией между формами (шаблон Event Aggregator);
— дальнейшее изучение шаблона по ссылкам ниже

Дизайн Windows Forms C#?

MaterialSkin сразу отпадает, попробую ModernUI

Может кто сталкивался с похожим вопросом?

Объясню на пальцах
1) Windows Forms родились во времена Windows 95 когда над дизайном окон в windows думали единицы.
Внедрение возможно, но это сродни пыткам и БДСМ, а какой-нибудь material Style вообще могут единицы на нем сделать, хотя в итоге выглядеть будет все равно как китайская подделка (присмотритесь к кривизне материал у телерика на формах в сравнении с андроидом, поймете о чем я)
2) MDI контейнер не используется с 2003го. (как вышел .net), вместо него сейчас более перспективные Docking либо tab-компоновка (см любой браузер) либо Ribbon.
Есть конечно исключения, например в Photoshop можно включить что-то вроде MDI режима, но это очень специфичные кейсы использования.

Уже только 2 этих фактора лишают вас каких либо современных методов/библиотек для интеграции кастомных дизайнов в проект

3) WPF.
Почему вы видите информацию в разрезе десктопного дизайна только про него.
Ну потому что, там оптимальное соотношение цена/время/качество в интеграции.
Можно сделать почти все что угодно, но для хардкора нужен большой скилл (как и везде впрочем)
Примеры можно посмотреть у меня https://inediapps.com/portfolio/
В будущем рекомендую переходить на данную платформу, хотя некоторые олдфаги могут тут со мной поспорить. Насчет актуальности — он быстрее форм, его Microsoft сейчас активно поддерживает, он opensource, поддержка тача и hiDPI, перспектива кроссплатформенности (Avalonia, Unity3D, Xamarin+.net5 …)

Вывод.
Понять, простить и забыть о дизайне MDI + WinForm.

C-sharp / Основы Windows Forms C# (изучаем основные формы)

За последние несколько лет Web-ориентированные приложения стали чрезвычайно популярными. Возможность размещать всю логику приложений на централизованном сервере выглядит очень привлекательной с точки зрения администратора. Развертывание программного обеспечения, базирующегося на клиенте, очень трудно, особенно, если оно основано на COM-объектах. Недостаток Web-ориентированных приложений состоит в том, что они не могут предоставить достаточно богатых возможностей пользователю.

Платформа .NET Framework позволяет разрабатывать интеллектуальные клиентские приложения с богатыми возможностями, при этом избегая проблем с развертыванием и “DLL-адом”, как это было раньше. Независимо от того, что будет выбрано — Windows Forms или Windows Presentation Foundation (см. главу 34) — разработка или развертывание клиентских приложений теперь не представляет особой сложности.

Windows Forms уже оказал влияние на разработки для Windows. Теперь, когда приложение находится на начальной стадии проектирования, принять решение о том, нужно ли строить Web-ориентированное приложение либо же полностью клиентское, стало немного труднее. Клиентские приложения Windows могут быть разработаны быстро и эффективно, при этом они предлагают пользователям гораздо более широкие возможности.

Windows Forms покажется вам знакомым, если у вас есть опыт разработки на Visual Basic. Вы создаете новые формы (также известные как окна или диалоги) в той же манере — перетаскивая и размещая элементы управления из панели инструментов на поверхность визуального дизайнера форм (Form Designer). Однако если ваш опыт в основном касается классического стиля языка C для Windows-программирования, где приходилось создавать конвейеры сообщений и отслеживать эти сообщения, или же если вы — программист, применяющий MFC, то в этом случае вы обнаружите, что и здесь при необходимости у вас есть возможность работать с низкоуровневыми деталями. Вы можете переопределить оконную процедуру (WndProc) и перехватывать сообщения, но в действительности вас удивит, что делать это придется нечасто.

В этой главе мы рассмотрим следующие аспекты Windows Forms:

иерархия классов Windows Forms;

элементы управления и компоненты, являющиеся частью пространства имен

меню и панели инструментов;

создание элементов управления;

создание пользовательских элементов управления.

Глава 31. Windows Forms 1055

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

Первое, что необходимо сделать — создать приложение Windows Forms. Для примера создадим пустую форму и отобразим ее на экране. При разработке этого примера мы не будем использовать Visual Studio .NET. Наберем его в текстовом редакторе и соберем с помощью компилятора командной строки. Ниже показан код примера.

using System.Windows.Forms; namespace NotepadForms

public class MyForm : System.Windows.Forms.Form

[STAThread] static void Main()

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

В приведенном коде заслуживают внимания две вещи. Первая — тот факт, что при создании класса MyForm используется наследование. Следующая строка объявляет

MyForm как наследника System.Windows.Forms.Form :

public class MyForm : System.Windows.Forms.Form

Класс Form — один из главных классов в пространстве имен System.Windows.Forms . Следующий фрагмент кода стоит рассмотреть более подробно:


[STAThread] static void Main()

Main — точка входа по умолчанию в любое клиентское приложение на C#. Как правило, в более крупных приложениях метод Main() не будет находиться в классе формы, а скорее в классе, отвечающем за процесс запуска. В данном случае вы должны установить имя такого запускающего класса в диалоговом окне свойств проекта. Обратите внимание на атрибут [STAThread] . Он устанавливает модель многопоточности COM в STA (однопоточный апартамент). Модель многопоточности STA требуется для взаимодействия с COM и устанавливается по умолчанию в каждом проекте Windows Forms.

Метод Application.Run() отвечает за запуск стандартного цикла сообщений приложения. Application.Run() имеет три перегрузки.

Первая из них не принимает параметров; вторая принимает в качестве параметра объект ApplicationContext . В нашем примере объект MyForm становится главной формой приложения. Это означает, что когда форма закрывается, то приложение завершается. Используя класс ApplicationContext , можно в большей степени контролировать завершение главного цикла сообщений и выход из приложения.

1056 Часть V. Презентации

Класс Application содержит в себе очень полезную функциональность. Он предоставляет группу статических методов и свойств для управления процессом запуска и останова приложения, а также обеспечивает доступ к сообщениям Windows, обрабатываемым приложением. В табл. 31.1 перечислены некоторые из этих наиболее полезных методов и свойств.

Таблица 31.1. Некоторые полезные методы и свойства класса Application

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

это БазовыйПуть\Название компании\Название продукта\Версия ,

где БазовыйПуть — C:\Documents and Settings\имя пользователя\

ApplicationData . Если путь не существует, он будет создан.

Путь и имя исполняемого файла, запускающего приложение.

, но с тем отличием, что поддерживается

True или false — в зависимости от того, существует ли цикл сообще-

ний в текущем потоке.

, с тем отличием, что имя файла не возвра-

Используется для предварительной обработки сообщений. Объект,

реализующий IMessageFilter , позволяет фильтровать сообщения в

цикле или организовать специальную обработку, выполняемую перед

тем, как сообщение попадет в цикл.

Аналогично оператору DoEvents языка Visual Basic. Позволяет обрабо-

тать сообщения в очереди.

Обеспечивает визуальный стиль Windows XP для различных визуальных

элементов приложения. Существуют две перегрузки, принимающие

информацию манифеста. Одна работает с потоком манифеста, вто-

рая — принимает полное имя и путь файла манифеста.

Exit и ExitThread

Exit завершает текущий работающий цикл сообщений и вызывает вы-

ход из приложения. ExitThread завершает цикл сообщений и закры-

вает все окна текущего потока.

А теперь как будет выглядеть это приложение, если его сгенерировать в Visual Studio 2008? Первое, что следует отметить — будет создано два файла. Причина в том, что Visual Studio 2008 использует возможность частичных ( partial ) классов и выделяет весь код, сгенерированный визуальным дизайнером, в отдельный файл. Если используется имя по умолчанию — Form1 , то эти два файла будет называться Form1.cs и Form1.Designer.cs . Если только у вас не включена опция Show All Files (Показать все файлы) в меню Project (Проект), то вы не увидите в проводнике Solution Explorer файла Form1.Designer.cs . Ниже показан код этих двух файлов, сгенерированных Visual Studio. Сначала — Form1.cs :

using System.Collections.Generic; using System.ComponentModel; using System.Data;

using System.Drawing; using System.Linq; using System.Text;

Глава 31. Windows Forms 1057

public partial class Form1 : Form

Здесь мы видим только операторы using и простой конструктор. А вот код Form1. Designer.cs :

partial class Form1

/// Required designer variable.

private System.ComponentModel.IContainer components = null;

/// Clean up any resources being used.

/// true if managed resources should be disposed; otherwise, false.

protected override void Dispose(bool disposing)

if (disposing && (components != null))


#region Windows Form Designer generated code

/// Required method for Designer support — do not modify

/// the contents of this method with the code editor.

private void InitializeComponent()

this.components = new System.ComponentModel.Container(); this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; this.Text = «Form1»;

Файл, сгенерированный дизайнером форм, редко подвергается ручному редактированию. Единственным исключением может быть случай, когда необходима специальная обработка в методе Dispose() . Метод InitializeComponent мы обсудим позднее в этой главе.

Если взглянуть на этот код примера приложения в целом, то мы увидим, что он намного длиннее, чем простой пример командной строки. Здесь перед началом класса присутствует несколько операторов using , и большинство из них в данном примере не нужны. Однако их присутствие ничем не мешает. Класс Form1 наследуется от

1058 Часть V. Презентации

System.Windows.Forms.Form , как и в предыдущем, введенном в Notepad примере, но в этой точке начинаются расхождения. Во-первых, в файле Form1.Designer появляется строка:

private System.ComponentModel.IContainer components = null;

В данном примере эта строка кода ничего не делает. Но, добавляя компонент в форму, вы можете также добавить его в объект components , который представляет собой контейнер. Причина добавления этого контейнера — в необходимости правильной обработки уничтожения формы. Класс формы поддерживает интерфейс IDisposable , потому что он реализован в классе Component . Когда компонент добавляется в контейнер, то этот контейнер должен позаботиться о корректном уничтожении своего содержимого при закрытии формы. Это можно увидеть в методе Dispose нашего примера:

protected override void Dispose(bool disposing)

if (disposing && (components != null))

Здесь мы видим, что когда вызывается метод Dispose формы, то также вызывается метод Dispose объекта components , поскольку он содержит в себе другие компоненты, которые также должны быть корректно удалены.

Конструктор класса Form1 , находящийся в файле Form1.cs , выглядит так:

Обратите внимание на вызов InitializeComponent() .

Метод InitializeComponent() находится в файле Form1.Designer.cs и делает то, что следует из его наименования — инициализирует все элементы управления, которые могут быть добавлены к форме. Он также инициализирует свойства формы.

В нашем примере метод InitializeComponent() выглядит следующим образом:

private void InitializeComponent()

this.components = new System.ComponentModel.Container(); this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; this.Text = «Form1»;

Как видите, здесь присутствует лишь базовый код инициализации. Этот метод связан с визуальным дизайнером Visual Studio. Когда в форму вносятся изменения в дизайнере, они отражаются на InitializeComponent() . Если вы вносите любые изменения в InitializeComponent() , то следующий раз после того, как что-то будет изменено в дизайнере, эти ручные изменения будут утеряны. InitializeComponent() повторно генерируется после каждого изменения дизайна формы. Если возникает необходимость добавить некоторый дополнительный код для формы или элементов управления и компонентов формы, это должно быть сделано после вызова InitializeComponent() . Этот метод также отвечает за создание экземпляров элементов управления, поэтому любой вызов, ссылающийся на них, выполненный до InitializeComponent() , завершится возбуждением исключения нулевой ссылки.

Глава 31. Windows Forms 1059

Чтобы добавить элемент управления или компонент в форму, нажмите комбинацию клавиш или выберите пункт меню View Toolbox (Вид Панель инструментов) в среде Visual Studio .NET. Щелкните правой кнопкой мыши на Form1.cs в проводнике Solution Explorer и в появившемся контекстном меню выберите пункт View Designer (Показать дизайнер). Выберите элемент управления Button и перетащите на поверхность формы в визуальном дизайнере. Можно также дважды щелкнуть на выбранном элементе управления, и он будет добавлен в форму. То же самое следует проделать с элементом TextBox .

Теперь, после добавления этих двух элементов управления на форму, метод InitializeComponent() расширяется и содержит такой код:

private void InitializeComponent()

this.button1 = new System.Windows.Forms.Button(); this.textBox1 = new System.Windows.Forms.TextBox(); this.SuspendLayout();

this.button1.Location = new System.Drawing.Point(77, 137); this.button1.Name = «button1»;

this.button1.Size = new System.Drawing.Size(75, 23); this.button1.TabIndex = 0;

this.button1.Text = «button1»; this.button1.UseVisualStyleBackColor = true;

this.textBox1.Location = new System.Drawing.Point(67, 75); this.textBox1.Name = «textBox1»;

this.textBox1.Size = new System.Drawing.Size(100, 20); this.textBox1.TabIndex = 1;

this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F); this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; this.ClientSize = new System.Drawing.Size(284, 264); this.Controls.Add(this.textBox1); this.Controls.Add(this.button1);

this.Name = «Form1»; this.Text = «Form1»; this.ResumeLayout(false); this.PerformLayout();

Если посмотреть на первые три строки кода этого метода, мы увидим в них создание экземпляров элементов управления Button и TextBox . Обратите внимание на имена, присвоенные им — textBox1 и button1 . По умолчанию дизайнер в качестве имен использует имя класса элемента управления, дополненное целым числом. Когда вы добавляете следующую кнопку, дизайнер называет ее button2 и т.д. Следующая строка — часть пары SuspendLayout / ResumeLayout . Метод SuspendLayout() временно приостанавливает события размещения, которые имеют место при первоначальной инициализации элемента управления. В конце метода вызывается ResumeLayout() , чтобы вернуть все в норму. В сложной форме с множеством элементов управления метод InitializeComponent() может стать достаточно большим.

1060 Часть V. Презентации

Чтобы изменить значения свойств элемента управления, нужно либо нажать , либо выбрать пункт меню View Properties Window (Вид Окно свойств). Это окно позволяет модифицировать большинство свойств элемента управления или компонента. При внесении изменений в окне свойств метод InitializeComponent() автоматически переписывается с тем, чтобы отразить новые значения свойств. Например, изменив свойство Text на My Button в окне свойств, получим следующий код в

this.button1.Location = new System.Drawing.Point(77, 137); this.button1.Name = «button1»;

this.button1.Size = new System.Drawing.Size(75, 23); this.button1.TabIndex = 0;

this.button1.Text = «My Button»; this.button1.UseVisualStyleBackColor = true;

Даже если вы предпочитаете использовать какой-то редактор, отличный от Visual Studio .NET, то наверняка захотите включать функции вроде InitializeComponent() в свои проекты. Сохранение всего кода инициализации в одном месте обеспечит возможность его вызова из каждого конструктора.

Важность понимания иерархии становится очевидной в процессе проектирования и конструирования пользовательских элементов управления. Если такой элемент управления унаследован от конкретного библиотечного элемента управления, например, когда создается текстовое поле с некоторыми дополнительными методами и свойствами, то имеет смысл унаследовать его от обычного текстового поля и затем переопределить и добавить необходимые методы. Однако если приходится создавать элемент управления, который не соответствует ни одному из существующих в .NET Framework, то его придется унаследовать от одного из базовых классов: Control или ScrollableControl , если нужны возможности прокрутки, либо ContainerControl , если он должен служить контейнером для других элементов управления.

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

Пространство имен System.Windows.Forms включает один класс, который является базовым почти для всех элементов управления и форм — System.Windows.Forms. Control . Он реализует основную функциональность для создания экранов, которые видит пользователь. Класс Control унаследован от System.ComponentModel.Component . Класс Component обеспечивает классу Control инфраструктуру, необходимую для того, чтобы его можно было перетаскивать и помещать на поле дизайнера, а также, чтобы он мог включать в себя другие элементы управления. Класс Control предлагает огромный объем функциональности классам, наследуемым от него. Этот список слишком большой, чтобы приводить его здесь, поэтому в данном разделе мы рассмотрим только наиболее важные возможности, предоставляемые классом Control . Позднее в этой главе, когда мы будем рассматривать специфические элементы управления, основанные на Control , мы увидим эти методы и свойства в коде примеров. Следующие

Глава 31. Windows Forms 1061


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

Размер и местоположение

Размер и местоположение элементов управления определяются свойствами Height , Width , Top , Bottom , Left и Right , вместе с дополняющими их Size и Location . Отличие состоит в том, что Height , Width , Top , Bottom , Left и Right принимают одно целое значение. Size принимает значение структуры Size , а Location — значение структуры Point . Структуры Size и Point включают в себя координаты X, Y. Point обычно описывает местоположение, а Size — высоту и ширину объекта. Size и Point определены в пространстве имен System.Drawing . Обе структуры очень похожи в том, что представляют пары координат X, Y, но, кроме того — переопределенные операции, упрощающие сравнения и преобразования. Вы можете, например, складывать вместе две структуры Size . В случае структуры Point операция сложения переопределена таким образом, что можно прибавить к Point структуру Size и получить в результате Point . Это дает эффект прибавления расстояния к местоположению, чтобы получить новое местоположение, что очень удобно для динамического создания форм и элементов управления.

Свойство Bounds возвращает объект Rectangle , представляющий экранную область, занятую элементом управления. Эта область включает полосы прокрутки и заголовка. Rectangle также относится к пространству имен System.Drawing . Свойство ClientSize — структура Size , представляющая клиентскую область элемента управления за вычетом полос прокрутки и заголовка.

Методы PointToClient и PointToScreen — удобные методы преобразования, которые принимают Point и возвращают Point . Метод PointToClient принимает структуру Point , представляющую экранные координаты, и транслирует их в координаты текущего клиентского объекта. Это удобно для операций перетаскивания. Метод PointToScreen выполняет обратную операцию — принимает координаты в клиентском объекте и транслирует их в экранные координаты.

Методы RectangleToScreen и ScreenToRectangle выполняют те же операции, но со структурами Rectangle вместо Point .

Свойство Dock определяет, к какой грани родительского элемента управления должен пристыковываться данный элемент. Перечисление DockStyle задает возможные значения этого свойства. Они могут быть такими: Top , Bottom , Right , Left , Fill и None . Значение Fill устанавливает размер данного элемента управления равным размеру родительского.

Свойство Anchor (якорь) прикрепляет грань данного элемента управления к грани родительского элемента управления. Это отличается от стыковки (docking) тем, что не устанавливает грань дочернего элемента управления точно на грань родительского, а просто выдерживает постоянное расстояние между ними. Например, если якорь правой грани элемента управления установлен на правую грань родительского элемента, и если родитель изменяет размер, то правая грань данного элемента сохраняет постоянную дистанцию от правой грани родителя — т.е. он изменяет размер вместе с родителем. Свойство Anchor принимает значения из перечисления AnchorStyle , а именно: Top , Bottom , Left , Right и None . Устанавливая эти значения, можно заставить элемент управления изменять свой размер динамически вместе с родителем. Таким образом, кнопки и текстовые поля не будут усечены или скрыты при изменении размеров формы пользователем.

Свойства Dock и Anchor применяются в сочетании с компоновками элементов управления Flow и Table (о которых мы поговорим позднее в этой главе) и позволя-

1062 Часть V. Презентации

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

Свойства, имеющие отношение к внешнему виду элемента управления — это

BackColor и ForeColor , которые принимают объект System.Drawing.Color в качестве значения. Свойство BackGroundImage принимает объект графического образа как значение. Класс System.Drawing.Image — абстрактный класс, служащий в качестве базового для классов Bitmap и Metafile . Свойство BackgroundImageLayout использует перечисление ImageLayout для определения способа отображения графического образа в элементе управления. Допустимые значения таковы: Center , Tile , Stretch ,

Свойства Font и Text работают с надписями. Чтобы изменить Font , необходимо создать объект Font . При создании этого объекта указывается имя, стиль и размер шрифта.

Взаимодействие с пользователем

Взаимодействие с пользователем лучше всего описывается серией событий, которые генерирует элемент управления и на которые он реагирует. Некоторые из наиболее часто используемых событий: Click , DoubleClick , KeyDown , KeyPress ,

События, связанные с мышью — Click , DoubleClick , MouseDown , MouseUp ,

MouseEnter , MouseLeave и MouseHover — описывают взаимодействие мыши и экранного элемента управления. Если вы обрабатываете оба события — Click и DoubleClick — то всякий раз, когда перехватывается событие DoubleClick , также возбуждается и событие Click . Это может привести к нежелательным последствиям при неправильной обработке. К тому же и Click , и DoubleClick принимают в качестве аргумента EventArgs , в то время как события MouseDown и MouseUp принимают MouseEventArgs . Структура MouseEventArgs содержит несколько частей полезной информации — например, о кнопке, на которой был выполнен щелчок, количестве щелчков на кнопке, количестве щелчков колесика мыши (при условии его наличия), текущих координатах X и Y указателя мыши. Если нужен доступ к любой подобной информации, то вместо событий Click или DoubleClick потребуется обрабатывать события MouseDown и MouseUp .

События клавиатуры работают подобным образом. Объем необходимой информации определяет выбор обрабатываемых событий. Для простейших случаев событие KeyPress принимает KeyPressEventArgs . Эта структура включает KeyChar , представляющий символ нажатой клавиши. Свойство Handled используется для определения того, было ли событие обработано. Установив значение Handled в true , можно добиться того, что событие не будет передано операционной системе для совершения стандартной обработки. Если необходима дополнительная информация о нажатой клавише, то больше подойдут события KeyDown или KeyUp . Оба принимают структуру KeyEventArgs . Свойства KeyEventArgs включают признак одновременного состояния клавиш , или . Свойство KeyCode возвращает значение типа перечисления Keys , идентифицирующее нажатую клавишу. В отличие от свойства KeyPressEventArgs.KeyChar , свойство KeyCode сообщает о каждой клавише клавиатуры, а не только о буквенно-цифровых клавишах. Свойство KeyData возвращает значение типа Keys , а также устанавливает модификатор. Значение модификатора со-

Глава 31. Windows Forms 1063

провождает значение клавиши, объединяясь с ним двоичной логической операцией “ИЛИ”. Таким образом, можно получить информацию о том, была ли одновременно нажата клавиша или . Свойство KeyValue — целое значение из перечисления Keys . Свойство Modifiers содержит значение типа Keys , представляющее нажатые модифицирующие клавиши. Если было нажато более одной такой клавиши, их значения объединяются операцией “ИЛИ”. События клавиш поступают в следующем порядке:

События Val >, Val >, Enter , Leave , GotFocus и LostFocus имеют отношение к получению фокуса элементами управления (т.е. когда становятся активными) и утере его. Это случается, когда пользователь нажатием клавиши переходит к данному элементу управления либо выбирает его мышью. Может показаться, что события Enter , Leave , GotFocus и LostFocus очень похожи в том, что они делают. События GotFocus и LostFocus относятся к низкоуровневым, и связаны с событиями Windows WM_SETFOCUS и WM_KILLFOCUS . Обычно когда возможно, лучше использовать события Enter и Leave . События Val >и Val >возбуждаются при проверке данных в элементе управления. Эти события принимают аргумент CancelEventArgs . С его помощью можно отменить последующие события, установив свойство Cancel в true . Если вы разрабатываете собственный проверочный код, и проверка завершается неудачно, то в этом случае можно установить Cancel в true — тогда элемент управления не утратит фокус. Val >происходит во время проверки, а Val >— после нее. Порядок возникновения событий следующий:

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

Пространство имен System.Windows.Forms — одно из немногих, полагающихся на функциональность операционной системы Windows. Класс Control — хороший тому пример. Если выполнить дизассемблирование System.Windows.Forms.dll , то можно увидеть список ссылок на класс UnsafeNativeMethods . Среда .NET Framework использует этот класс как оболочку для всех стандартных вызовов Win32 API. Благодаря возможности взаимодействия с Win32 API, внешний вид и поведение стандартного приложения Windows можно обеспечить средствами пространства имен System. Windows.Forms .

Функциональность, которая поддерживает взаимодействие с Windows, включает свойства Handle и IsHandleCreated . Свойство Handle возвращает IntPtr , содержащий HWND (дескриптор окна) элемента управления. Дескриптор окна — это HWND , уни-

Введение в 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

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

Цукерберг рекомендует:  Blur - Помогите новичку в CSS
Понравилась статья? Поделиться с друзьями:
Все языки программирования для начинающих
Примечание