Что содержит файл form1 cs
Теперь посмотрим на содержимое файла Form1.cs. Если раскрыть ветку формы, то вы увидите, что там есть еще два файла: Form1.Designer.cs и Form.resx. Получается, что форма описана аж в трех файлах? Да, так и есть. Конечно же, все можно было реализовать в одном файле с кодом, но такое разбиение сделано для вашего же удобства
5.2.3. Именование формы
Мы уже говорили, что все переменные нужно именовать понятными словами. Никаких имен типа Form1 в реальных приложениях быть не должно. Но нельзя переименовывать просто так переменную класса, особенно если это форма. Тут лучше переименовать файл.
Щелкните правой кнопкой мыши по имени файла формы в панели Solution Explorer и из контекстного меню выберите пункт Rename (Переименовать). Введите новое имя формы, и будут переименованы не только имена файлов, связанных с формой, но и класс, находящийся внутри. При этом изменения произойдут во всех файлах, где задействована форма, в том числе и в файле Program.cs.
5.2.4. Код, сгенерированный дизайнером
Раньше весь код, который касался формы, находился в одном файле кода. Но это было неудобно, потому что размер файла рос с сумасшедшей скоростью, и управление им становилось неудобным. Сейчас среда разработки разбивает код на два файла. В одном файле (Form1.cs) мы пишем всю свою логику — его мы рассмотрели в разд. 5.2.2, а в другом файле (Form1.Designer.cs) среда разработки сохраняет весь необходимый код для реализации того, что мы сделаем визуально в дизайнере.
Мы пока ничего не делали в дизайнере, но давайте посмотрим, что уже есть в файле Form1.Designer.cs. Для этого щелкните по нему правой кнопкой мыши и из контекстного меню выберите пункт View Code. Код того, что сгенерировал дизайнер в моем случае, показан в листинге 5.2.
Листинг 5.2. Код файла Form1.Designer.cs
В этом файле нет никаких подключений пространств имен, потому что весь код в файле пишется дизайнером автоматически, и мы сюда будем заглядывать очень редко, а редактировать его еще реже. Дизайнер достаточно интеллектуален, поэтому, чтобы ничего не подключать, он просто будет обращаться ко всем методам и типам данных по полному имени с указанием полного пути в пространстве имен.
Итак, в файле Form1.Designer.cs идет продолжение объявления класса Form1. Об этом говорит то, что в самом начале снова идет объявление класса Form1 и указан модификатор partial. То есть все, что будет описано в классе этого модуля, добавится к конструктору, который мы уже рассмотрели в разд. 5.2.2.
Далее идет метод Dispose(), который будет вызываться системой, когда возникнет необходимость уничтожить объект класса формы. В двух словах поясню, что происходит в этом методе: вызывается метод Dispose() переменной components, чтобы она почистила за собой, и вызывается этот же метод базового класса формы.
После метода Dispose() начинается самое интересное, а именно — вызов метода InitializeComponent(). Вы не видите этого метода? Но вы видите следующую строку, написанную серым цветом?
Вернемся к методу InitializeComponent(). Вспомните разд. 5.2.2, где мы рассматривали конструктор нашей формы. Там мы говорили о том, что в конструкторе вызывается метод с точно таким же именем. Так вот он где находится! И хотя он реализован в другом файле, но, все же, остается частью того же partial-класса.
Несмотря на то, что название метода InitializeComponent() переводится как "инициализировать компонент", метод инициализирует свойства формы, а также создает все элементы управления, которые мы поставим на форму визуально. Да, именно визуально и только визуально. Ручками в этот метод ничего писать не рекомендуется, иначе дизайнер может оказаться не способным понять ваши благие намерения и ваш мегакод, — при попытке открыть форму в дизайнере он вернет ошибку. Если и возникнет необходимость вносить какие-то изменения в метод InitializeComponent(), то делайте это очень аккуратно и осторожно.
Теперь одним глазком посмотрим, что происходит внутри этого метода. В самом начале вызывается метод SuspendLayout() для нашей формы (о том, что вызывается метод именно текущей формы, говорит слово this). Этот метод заставляет систему приостановить реагирование на изменение атрибутов. Дело в том, что при изменении любого атрибута система будет перерисовывать форму. При инициализации чаще всего приходится изменять сразу несколько атрибутов, и после изменения каждого из них реагировать и изменять форму невыгодно. Намного эффективнее изменить все атрибуты, а потом уже пусть форма один раз отреагирует на все изменения и прорисуется в соответствии с изменениями в нужном месте.
Итак, после вызова метода SuspendLayout() для нашего окна оно не будет реагировать и изменять свою форму при изменении атрибутов, а сделает это после вызова метода ResumeLayout().
Далее идет изменение свойств формы. Мы пока не будем рассматривать эти свойства, все придет со временем. Хочу только сказать, что среда разработки и генератор этого кода мудры, как никто более, и помогают нам, как только возможно. Так что, в методе InitializeComponent() появится код для инициализации всех кнопок, которые вы будете располагать на форме, и всех других элементов управления. Чтобы проще было работать с методом, генератор будет группировать код так, чтобы код инициализации одного элемента управления находился в одном месте, а не был разбросан по всему методу InitializeComponent().
К тому же, перед началом инициализации очередного элемента будет вписан комментарий с указанием имени элемента управления, свойства которого будут далее изменяться. В нашем примере нет ничего кроме формы, но, несмотря на это, перед началом изменения ее свойств стоит комментарий. Спасибо разработчикам Visual Studio за то, что не забывают о нас.
Настройка компиляции проекта
В итоге нам откроектся файл с расширением csproj , который называется по имени проекта (например, HelloApp.csproj) со следующим содержимым:
Для компиляции приложения Windows Forms указаны следующие настройки:
OutputType : определяет выходной тип проекта. Должен иметь значение WinExe - то есть выполняемое приложение с расширением exe под Windows
Nullable : подключает в проект функционалность ссылочных nullable-типов
UseWindowsForms : указывает, будет ли проект использовать Windows Forms (для этого устанавливается значение true )
ImplicitUsings : подключает в проект функциональность неявно подключаемых глобальных пространств имен
Запуск приложения
Чтобы запустить приложение в режиме отладки, нажмем на клавишу F5 или на зеленую стрелочку на панели Visual Studio.
После этого запустится пустая форма Form1 по умолчанию.
После запуска приложения студия компилирует его в файл с расширением exe. Найти данный файл можно, зайдя в папку проекта и далее в каталог \bin\Debug\net6.0-windows
Рассмотрев вкратце создание проекта графического приложения, мы можем перейти к обзору основных компонентов и начнем мы с форм.
Одним из преимуществ разработки в Visual Studio приложений Windows Forms является наличие графического редактора, который позволяет в графическом виде представить создаваемую форму и в принципе упрощает работу с графическими компонентами.
Для открытия формы в режиме графического дизайнера нажмем на в структуре проекта на файл Form1.cs либо левой кнопкой мыши двойным кликом, либо правой кнопкой мыши и в появившемся контекстном меню выберем View Designer (также можно использовать комбинацию клавиш Shift+F7)
После этого в Visual Studio откроется выбранная форма в графическом виде.
В то же время следует отметить, что на более слабых компьютерах окно дизайнера можно открываться довольно долго, а на некоторых - довольно слабых компьютерах может и вообще не открыться.
При выборе формы в окне дизайнера внизу справа под структурой проекта мы сможем найти окно Properties (Свойства). Так как у меня в данный момент выбрана форма как элемент управления, то в этом поле отображаются свойства, связанные с формой.
Теперь найдем в этом окне свойство формы Text и изменим его значение на любое другое:
Таким образом мы поменяли заголовок формы. И подобным образом мы можем поменять другие свойства формы, которые доступны в окне свойств.
Найдем среди элементов кнопку и, захватив ее указателем мыши, перенесем на форму:
Причем при выборе кнопки она открывается в окне свойств и, как и для всей формы, для кнопки в окне свойств мы можем изменить значения различных свойств.
Кроме того, если после переноса кнопки на форму мы откроем файл Form1.
Мы видим, что в класс Form1 была добавлена переменная button1 типа Button и для этой переменной, как и для объекта формы, задан ряд свойств. И если в окне свойств мы поменяем значения этих свойств, то в этом файле также изменяться их значения. Как в случае с текстом формы:
Изменим этот код следующим образом:
Стоит отметить, что графический дизайнер позволяет автоматически сгенерировать обработчик нажатия кнопки. Для этого надо в окне дизайнера нажать на кнопку на форме двойным щелчком мыши.
Мы уже увидели, что свойства могут изменяться как визуально, так и программно. Визуальные изменения дизайнер оформляет в коде метода InitializeComponent(). Если вы решили сами делать изменения свойств в коде, то это можно сделать в конструкторе и обязательно после вызова метода InitializeComponent(). Если написать код изменений до вызова этого метода, то они могут оказаться бессмысленными, если дизайнер в методе инициализации компонентов сгенерирует свой код.
Откройте сейчас код формы (Form1.cs) и попробуйте в коде конструктора присвоить свойству Text текущей формы какое-нибудь значение — например, как показано в следующем примере:
Рис. 5.6. Панель выбора цвета
- BackgroundColor — цвет фона окна. Это свойство имеет тип класса Color. Если щелкнуть в поле напротив свойства, то появится кнопка выпадающего списка. Щелкните по ней, и вы увидите панель выбора цвета (рис. 5.6).
Панель состоит из трех вкладок: Custom (Произвольные), Web (Web-цвета) и System (Системные). Для окон желательно указывать один из системных цветов и лучше, если это будет Control для диалоговых окон и Window для окон, которые должны отображать данные; - Cursor — позволяет задать тип курсора, который будет отображаться в момент, когда курсор мыши находится над поверхностью окна. При изменении этого свойства в визуальном дизайнере появляется выпадающий список, в котором перечислены названия типов курсоров и даже показаны их изображения;
- Enabled — позволяет задать доступность окна. Если свойство равно false, то компонент не станет реагировать на действия пользователя, т. е. будет недоступен;
- Font — шрифт, который будет использоваться для вывода текста поверх окна. Для окна это, на первый взгляд, не очень актуально. Но большая актуальность этого свойства проявляется у компонентов, которые содержат надписи. Чтобы изменить шрифт, можно поступить двумя способами:
- выделить строку со свойством Font, и в правом углу появится кнопка с тремя точками. Щелкните по ней, и вы увидите стандартное окно задания свойств шрифта;
- свойство шрифта на самом деле является самостоятельным классом Font со своими свойствами. Вы можете редактировать их каждое в отдельности. Для этого нужно щелкнуть по кнопке с крестиком слева от имени свойства. В окне Properties свойства формы расступятся, уступив место свойствам шрифта (рис. 5.7);
- None — контура не будет;
- FixedSingle — тоненький фиксированный контур, не позволяющий изменять размеры окна;
- Fixed3D — контур фиксированный, не позволяющий изменять размеры окна, но трехмерный, создающий эффект заглубленного окна;
- FixedDialog — похож на FixedSingle, только в заголовке окна не будет значка. Такой контур чаще всего используют для диалоговых окон;
- Sizable — стандартный контур, позволяющий изменять размеры окна;
- FixedToolWindow — контур с очень тоненьким заголовком окна, не позволяющий изменять размеры окна. Такие окна чаще всего используются для окон с кнопками — например, окно инструментов в Adobe Photoshop;
- SizableToolWindow — то же самое, что и FixedToolWindow, только с возможностью изменять размер окна;
- WindowsDefaultLocation — положение окна определяется ОС;
- WindowsDefaultBounds — система будет определять не только положение, но и размеры окна;
- CenterParent — расположить окно по центру родительского окна. На мой взгляд, это значение лучше всего использовать для всех дочерних окон;
- Manual — расположение будет задаваться программистом самостоятельно через свойство Location;
- CenterScreen — отцентрировать по центру экрана;
- Normal — нормальное состояние;
- Maximized — окно должно быть развернуто на весь экран;
- Minimized — окно должно быть минимизировано.
Рис. 5.7. Свойства для настройки свойств шрифта
Напоминаю, что эта книга — не справочник по функциям, такой справочник уже есть, и называется он MSDN. Мы рассматриваем только самое интересное и учимся программировать.
Почему я рассмотрел указанные свойства? Большинство из них есть не только у форм, но и у любого типа визуальных компонентов. Просто они наследуются от общих для всех компонентов предков. К тому же, я выбрал разные типы, чтобы вы увидели, что в окне свойств для редактирования различных компонентов могут вызываться разные редакторы.
Теперь давайте посмотрим, что скрывают под собой кнопки с крестиками слева от некоторых свойств. Крестики могут стоять у тех свойств, которые сами по себе являются объектами определенного класса. Например, свойство Font является классом Font. Раскрывая крестик у свойства Font, вы увидите свойства класса Font. А раскрыв шрифт Font, вы можете увидеть свойство Size — размер. Полный путь к размеру шрифта будет выглядеть так:
Сразу же следует рассмотреть структуры данных, с которыми вы будете встречаться при работе с компонентами и формами: Size и Location. Рассмотрим каждую в отдельности.
Структура Size предназначается для задания размеров — например, размеров компонента или формы. У структуры есть два поля: Width и Height — для указания ширины и высоты соответственно. Вы не можете изменять свойства структуры, и следующая строка приведет к ошибке компиляции:
Всегда нужно создавать новый экземпляр структуры. Например, следующий пример устанавливает размеры окна в 200300:
Тип данных Size используется также для свойств MaximumSize, MinimumSize, AutoScrollMargin и AutoScrollMinSize.
Структура Location имеет тип Point. И, судя по названию, с ее помощью чаще всего задают точку. Часто этот тип служит для задания положения компонента или формы. Эта структура содержит два важных свойства: X и Y, которые хранят смещения по соответствующим координатным осям. Следующая строка перемещает текущую форму в позицию 1010:
У обеих структур свойства, задающие размер и положение, имеют тип данных целого числа int. Вы не можете задать дробное число в качестве указателя положения, да это и не имеет смысла в WinForms, — ведь размеры формы и положение определяются пикселами, а это минимальная единица в таком случае, и она не может дробиться.
5.2.5. Hello Visual World
Теперь вы можете запустить приложение с помощью клавиши , как мы это делали в случае с консольными приложениями. На экране должно появиться окно таких же размеров, какие были в окне дизайнера.
Чтобы наш пример стал полноценным приложением "Hello World", но только из визуального окна, давайте изменим заголовок окна. Для этого нужно переключиться на визуальную форму, что можно сделать несколькими способами — например, просто щелкнуть двойным щелчком по имени файла Form1.cs в панели Solution Explorer. По умолчанию формы с визуальным интерфейсом открываются именно в визуальном дизайнере. Если в вашей среде разработки произошло не так, то можно щелкнуть правой кнопкой мыши по имени файла и из контекстного меню выбрать View Designer (Показать дизайнер). Если вы находитесь в окне кода, можно нажать комбинацию клавиш + .
В дизайнере должна быть выбрана форма, тогда в панели Properties появятся свойства формы (рис. 5.5). Вообще-то, у нас ничего, кроме формы, нет, поэтому суетиться рано, — все равно будут отображаться свойства именно формы, но главное, чтобы панель Properties присутствовала на экране. Если вы ее не видите, выберите в главном меню View | Properties Window.
Рис. 5.5. Панель Properties со свойствами формы
В панели Properties в левом столбце найдите свойство Text и напротив него измените в правом столбце название заголовка на Hello World (по умолчанию оно равно имени класса). Вот теперь можно запускать приложение снова и наблюдать в заголовке окна великую фразу, с которой начинали учиться программированию многие знаменитые программисты.
Мы сделали небольшое изменение, но оно очень важно для нас, потому что мы узнали, как работать со свойствами в визуальном дизайнере, и научились изменять их значения. Теперь можете вернуться в файл Form1.Designer.cs и посмотреть на метод инициализации компонентов. Обратите внимание на следующую строку кода:
В ответ на изменение в визуальном дизайнере среда разработки сгенерировала соответствующий код. Мы могли бы ручками написать этот же код, ведь здесь просто свойству Text текущего объекта присваивается строка, но через визуальный дизайнер это делать интереснее и проще.
Внешний вид приложения является нам преимущественно через формы. Формы являются основными строительными блоками. Они предоставляют контейнер для различных элементов управления. А механизм событий позволяет элементам формы отзываться на ввод пользователя, и, таким образом, взаимодействовать с пользователем.
При открытии проекта в Visual Studio в графическом редакторе мы можем увидеть визуальную часть формы - ту часть, которую мы видим после запуска приложения и куда мы переносим элементы с панели управления. Но на самом деле форма скрывает мощный функционал, состоящий из методов, свойств, событий и прочее. Рассмотрим основные свойства форм.
Если мы запустим приложение, то нам отобразится одна пустая форма. Однако даже такой простой проект с пустой формой имеет несколько компонентов:
Несмотря на то, что мы видим только форму, но стартовой точкой входа в графическое приложение является класс Program, расположенный в файле Program.cs:
Сама форма сложна по содержанию. Она делится на ряд компонентов. Так, в структуре проекта есть файл Form1.Designer.cs, который выглядит примерно так:
Здесь объявляется частичный класс формы Form1, которая имеет два метода: Dispose() , который выполняет роль деструктора объекта, и InitializeComponent() , который устанавливает начальные значения свойств формы.
При добавлении элементов управления, например, кнопок, их описание также добавляется в этот файл.
Но на практике мы редко будем сталкиваться с этим классом, так как они выполняет в основном дизайнерские функции - установка свойств объектов, установка переменных.
Еще один файл - Form1.resx - хранит ресурсы формы. Как правило, ресурсы используются для создания однообразных форм сразу для нескольких языковых культур.
И более важный файл - Form1.cs, который в структуре проекта называется просто Form1, содержит код или программную логику формы:
По умолчанию здесь есть только конструктор формы, в котором просто вызывается метод InitializeComponent() , объявленный в файле дизайнера Form1.Designer.cs. Именно с этим файлом мы и будем больше работать.
После установки среды и всех ее компонентов, запустим Visual Studio и создадим проект графического приложения. На стартовом экране выберем Create a new project (Создать новый проект)
На следующем окне в качестве типа проекта выберем Windows Forms App :
Далее на следующем этапе нам будет предложено указать имя проекта и каталог, где будет располагаться проект.
В поле Project Name дадим проекту какое-либо название. В моем случае это HelloApp .
После этого Visual Studio откроет наш проект с созданными по умолчанию файлами:
Справа находится окно Solution Explorer, в котором можно увидеть структуру нашего проекта. В данном случае у нас сгенерированная по умолчанию структура:
Далее идет файл единственной в проекте формы - Form1.cs , который по умолчанию открыт в центральном окне:
Класс формы - Form1 представляет графическую форму - фактически то окно, которое мы увидим на экране при запуске проекта.
Этот класс определяется как частичный (с модификатором partial ) и наследуется от встроенного класса Form , который содержит базовую функциональность форм.
В самом классе Form1 определен по умолчанию только конструктор, где вызывается метод InitializeComponent() , который выполняет инициализацию компонентов формы из файла дизайнера.
Рядом с этим элементом можно заметить другой файл формы - Form1.Designer.cs . Это файл дизайнера - он содержит определение компонентов формы, добавленных на форму в графическом дизайнере и именно его код по сути передается выше через вызов InitializeComponent()
Program.cs определяет точку входа в приложение:
Метод Main снабжен атрибутом [STAThread] . Этот атрибут, грубого говоря, необходим для корректной работы компонентов Windows. В самом методе сначала вызывается метод
который устанавливает некоторую базовую конфигурацию приложения
Затем вызывается метод
в который передается объект отображаемой по умолчанию на экране формы.
5.2.2. Файл для логики модуля
Теперь посмотрим на содержимое файла Form1.cs. Если щелкнуть по файлу двойным щелчком, то он откроется в режиме визуального дизайна, где вы можете расставлять компоненты. Чтобы увидеть код формы, нужно нажать клавишу или щелкнуть правой кнопкой мыши по имени файла в панели Solution Explorer и из контекстного меню выбрать View Code (Показать код).
В самом начале файла, как всегда, осуществляется подключение пространств имен, которые мы можем использовать в модуле. Мастер подключил пространства имен с большим запасом, потому что для компиляции кода, который находится сейчас в модуле, достаточно только System и System.Windows.Forms. Все остальное добавлено, потому что в Microsoft посчитали, что оно вам пригодится.
Пространства имен я опустил, а все остальное показано в следующем коде:
Сразу же видим, что весь код также объявлен в пространстве имен OurFirstVisualApplication. Внутри этого пространства объявляется открытый класс с именем Form1, который является наследником класса Form. В этом объявлении много чего интересного, что мы еще не рассматривали.
В данном случае у нас не просто экземпляр класса, а его наследник. Просто экземпляра было бы достаточно, если бы мы лишь изменили его свойства и отобразили. Но чем может быть полезно пустое окно? Ничем! Поэтому мы создаем наследника и будем расширять его возможности, добавляя меню, кнопки и панели, а не только изменять свойства.
Вообще-то, создать форму и налепить на нее компоненты можно и без наследования, но мне кажется, что такой подход будет не очень удобным и эффективным. Класс должен быть автономным и должен сам расставлять на поверхности все необходимые компоненты. То, что мы можем поставить компоненты извне, не означает, что это хороший способ. При проектировании класса всегда старайтесь делать его автономным и максимально независящим от внешних факторов.
Очень интересным модификатором в начале объявления класса является partial. Он означает, что объявление класса разбито на несколько файлов с кодом. Перед нами первый из этих файлов, а, забегая вперед, скажу, что продолжение реализации класса находится в файле Form1.Designer.cs. Это очень мощная возможность — когда вы можете разбить реализацию класса на несколько файлов. Например, в одном файле вы реализуете все методы, в другом — все свойства, а в третьем объявляете дополнительные переменные. Для этого нужно, чтобы во всех трех файлах было объявление класса с одним и тем же именем и с модификатором partial.
Внутри класса в файле Form1.cs определяется только конструктор, в котором вызывается метод InitializeComponent(). Что это такое, и откуда взялся этот метод?
В нем инициализируются все свойства формы и компоненты, которые могут быть установлены на форме. Но где он объявлен и как выглядит? Об этом мы узнаем в разд. 5.2.4.
5.2.1. Ресурсы программы
В RESX-файле хранятся атрибуты файла кода, и с ним работает среда разработки. Мне пока еще ни разу не приходилось редактировать его напрямую, в основном я делал это из среды разработки. Помните, что в нем среда разработки сохраняет параметры формы для внутреннего использования и ресурсы программы.
Но есть глобальный файл ресурсов, с которым вы можете работать без проблем. Он находится в папке Properties проекта и называется Resources.resx. В нем расположены ресурсы приложения, и они могут быть доступны любой форме проекта.
Вы можете создавать в файле RESX ресурсы — такие как строки, изображения и т. д., которые в последующем можно будет использовать в программе.
Попробуйте щелкнуть двойным щелчком по файлу Form1.resx в панели Solution Explorer. Перед вами откроется редактор ресурсов формы (рис. 5.4).
Рис. 5.4. Окно редактирования ресурсов формы
В панели инструментов редактора ресурсов заголовок первой кнопки указывает на тот модуль, который сейчас открыт. На рис. 5.4 открыт модуль редактирования строк (кнопка называется Strings). Если щелкнуть на стрелке вниз справа от кнопки Strings, то появится всплывающее меню, и из него вы можете выбрать тип ресурсов, которые можно редактировать. Существуют следующие типы ресурсов (в скобках указаны горячие клавиши для вызова соответствующего модуля редактирования):
- Strings ( + ) — строки;
- Images ( + ) — картинки;
- Icons ( + ) — значки;
- Audio ( + ) — аудиозаписи;
- Files ( + ) — файлы;
- Other ( + ) — что-то другое, например пользовательские данные.
Для добавления нового ресурса такого же типа, что и открытый модуль, достаточно щелкнуть по кнопке Add Resource (Добавить ресурс) на панели инструментов. Чтобы выбрать тип ресурса и метод создания, щелкните по стрелке вниз справа от кнопки Add Resource. В выпадающем меню можно выбрать создание ресурса на основе существующего файла или сделать выбор типа изображения для ресурса типа Image.
Читайте также: