визуальное проектирование приложений c
Визуальное проектирование приложений c
Визуальное проектирование приложений C#
А.В. Фролов, Г.В. Фролов
Приведена информация, необходимая для быстрого создания деловых приложений со сложным пользовательским интерфейсом, интегрированных с базами данных. Описаны приемы проектирования диалоговых окон, элементов управления и других компонентов. Имеется большое количество примеров исходных программ, снабженных необходимыми комментариями.
За счет чего средства RAD ускоряют разработку приложений?
Во многом это происходит благодаря применению графических средств проектирования пользовательского интерфейса.
Напомним, что первое время приложения для операционной системы (ОС) Microsoft Windows создавались при помощи инструментов, предполагающих использование обычных редакторов текста, дополненных средствами синтаксического выделения конструкций языка, средствами отладки и справочно-информационными системами.
Формально Microsoft Visual C ++ в комплекте с библиотекой классов Microsoft Foundation Classes ( MFC ) может выступать в качестве системы визуального проектирования приложений. Однако на деле создание с его помощью программ, имеющих по-настоящему сложный пользовательский интерфейс, совсем не просто.
Упрощенно, процесс визуальной разработки приложений в Borland Delphi и Microsoft Visual Basic заключается в графическом проектировании внешнего вида (дизайна) приложений, с последующей привязкой программного кода к элементам пользовательского интерфейса. При этом для решения самых нужных задач (таких, например, как обращение к базам данных) используется богатая библиотека программных компонентов.
Создавая новую программу, разработчик имеет дело с графическим представлением ее главного окна и всех других окон. Перемещая мышью в эти окна из специальных палитр значки элементов интерфейса (кнопок, меню и т.д.), а также значки программных компонентов (соединений с базами данных, компонентов управления меню и др.), программист может очень быстро получить работающий скелет программы. При этом размещение элементов интерфейса и настройка их размеров производится простым и понятным образом. Фактически, программист просто «рисует» окна своего приложения, быстро достигая необходимого результата.
Когда скелет программы создан, его следует наполнить необходимой функциональностью. Щелкая мышью элементы пользовательского интерфейса и значки программных компонентов в окне проектируемого приложения, программист вводит в редакторе текста программный код, предназначенный для работы с этими элементами. В результате намного упрощается процедура привязки программного кода к элементам пользовательского интерфейса и другим компонентам приложения.
Какого-либо опыта создания приложений для ОС Microsoft Windows не требуется, хотя, без сомнения, этот опыт будет очень полезен. Мы, однако, полагаем, что Вы хорошо владеете приемами работы с готовыми приложениями Windows на уровне опытного пользователя.
Во второй главе Вы научитесь создавать проекты приложений и отлаживать приложения C # с визуальным графическим интерфейсом.
Глава 3 расскажет Вам о создании форм в приложениях C #. Формы представляют собой важнейший компонент приложений, с помощью которого создаются окна программы. Вы научитесь добавлять в формы такие элементы управления, как текстовые поля и кнопки, настраивать внешний вид и поведение формы, создавать обработчики событий, расположенных в окне формы.
В 4 главе на практическом примере редактора текста мы рассмотрим многие аспекты создания приложений с визуальным интерфейсом. Вы научитесь добавлять в форму меню и строку состояния, загружать, сохранять и распечатывать файлы текстовых документов, словом, все основное, что нужно для создания большинства приложений.
Глава 5 посвящена диалоговым окнам, с которыми приходится сталкиваться практически каждому разработчику приложений с визуальным графическим интерфейсом. Мы рассмотрим как простейшие диалоговые окна, предназначенные для отображения сообщений, так и сложные, способные получать, обрабатывать и возвращать данные. Вы узнаете о модальных и немодальных окнах, а также о способах проверки данных, введенных пользователями в формах ввода, реализованных с помощью диалоговых окон.
Мы расскажем Вам также в 10 главе о рисовании изображений, хранящихся в файлах различных графических форматов. Мы создадим программу просмотра таких файлов, способную отображать изображения, пиктограммы которых пользователь может перетаскивать методом буксировки из папок в окно программы просмотра. И в заключение мы расскажем о шрифтах и способах выбора шрифтов для рисования текста.
Визуальное проектирование приложений c
Визуальное проектирование приложений C#
А.В. Фролов, Г.В. Фролов
Обнаружив отсутствие перечисленный выше компонентов, мастер установки выведет на экран предупреждающее сообщение, показанное на рис. 2-2.
Рис. 2-2. Предупреждающее сообщение о необходимости установки IIS
Рис. 2-3. Список обновляемых компонентов
И еще один важный момент.
Практически все существующие системы разработки программного обеспечения используют так называемую концепцию проекта ( project ). Проект объединяет все файлы, необходимые для редактирования, трансляции и отладки приложения. Это файлы исходных текстов, объектных и загрузочных модулей, файлы ресурсов приложений и т.п.
В простейшем случае исходный текст программы помещается в одном файле. Исходные тексты сложных приложений могут насчитывать десятки и сотни файлов различного типа. Объединение в проект всех файлов, имеющих отношение к разработке приложения, облегчает управление всем этим файловым хозяйством.
Примеры приложений, приведенных в нашей книге, будут реализованы с использованием одного решения, в котором находится только один проект. Однако при необходимости Вы сможете создавать и более сложные решения.
Рис. 2-6. Мастер проектов
Рис. 2-7. Проект Hello создан
Рис. 2-8. Работает программа Hello
Рис. 2-9. Вкладка Start Page
Ссылка What ’ s New позволит просмотреть различные новости, интересные разработчикам приложений.
Рис. 2-10. Панель элементов управления
Далее, опять же при помощи мыши, нужно перетащить значки необходимых Вам элементов управления на поверхность создаваемой формы. На рис. 2-10 мы разместили таким способом в нашей форме две кнопки и два текстовых поля.
Если это требуется, то с помощью мыши можно отрегулировать размеры и расположение элементов управления, добавленных в форму, а также размеры самой формы.
Рис. 2-11. Окно Solution Explorer
Рис. 2-12. Окно редактирования значка приложения
Рис. 2-13. Окно редактирования исходного текста приложения
Это окно содержит полный исходный текст нашего приложения, созданного автоматически мастером проектов. По мере добавления в форму новых элементов управления, этот исходный текст будет автоматически модифицироваться. Вам тоже придется «приложить руки» к редактированию этого текста, так как программирование обработчиков событий, создаваемых элементами управления, выполняется вручную.
Обратите внимание на вертикальные линии, расположенные в левой части окна редактирования (рис. 2-13). Эти линии, снабженные флажками в виде прямоугольников, ограничивают фрагменты текста. Щелкая эти флажки, можно свертывать или разворачивать соответствующие фрагменты текста.
Когда фрагмент текста свернут, соответствующий флажок отмечен знаком плюс, а когда развернут — знаком минус.
Рис. 2-14. Сокрытие фрагментов исходного текста
Возможность сворачивать и разворачивать фрагменты редактируемого теста Вы оцените, когда перейдете к работе над крупными проектами. Она позволит Вам быстрее находить нужные фрагменты текста, избавив от необходимости последовательного просмотра листинга.
Практически каждый компонент создаваемого приложения, такой как форма или элемент управления, имеет свой набор свойств. Для формы, например, можно задавать такие свойства, как цвет фона, заголовок, наличие фонового графического изображения, внешний вид рамки и т.д. Кнопка обладает таким свойством, как цвет, текст надписи и др.
Рис. 2-15. Окно просмотра и редактирования свойств объектов
Пользоваться им очень просто. В левой части этого окна на вкладке Properties располагается список свойств и групп свойств, а в правой — значения свойств. В зависимости от разных обстоятельств некоторые из свойств поддаются редактированию, а некоторые — нет.
Создавая приложения, мы будем постоянно ссылаться на это окно, т.к. настройка свойств объектов выполняется очень часто. Заметьте, что некоторые числовые и строчные значения можно вводить в полях редактирования, а некоторые нужно выбирать из списков. Для выбора цвета на экран выводятся специальные палитры.
Полный исходный текст первого варианта программы Hello Вы найдете в листинге 2-1. Далее мы будем исследовать его по частям.
Листинг 2-1. Файл ch 02\ hello \ Form 1. cs
using System;
using System.Drawing;
using System.Collections;
using System.ComponentModel;
using System.Windows.Forms;
using System.Data;
namespace Hello
<
///
/// Summary description for Form1.
///
public class Form1 : System.Windows.Forms.Form
<
///
/// Required designer variable.
///
private System.ComponentModel.Container components = null;
public Form1()
<
//
// Required for Windows Form Designer support
//
InitializeComponent();
//
// TODO: Add any constructor code
// after InitializeComponent call
//
>
///
/// The main entry point for the application.
///
[STAThread]
static void Main()
<
Application.Run(new Form1());
>
>
>
В самое начало фала исходного текста приложения мастер проектов вставил строки, подключающие несколько пространств имен ( name space ) с помощью ключевого слова using :
using System;
using System.Drawing;
using System.Collections;
using System.ComponentModel;
using System.Windows.Forms;
using System.Data;
Пространство имен System содержит определение фундаментальных и базовых классов, определяющих типы данных, события, обработчики событий и другие, необходимые в каждом приложении компоненты.
В пространстве имен System.Collections определены классы, реализующие функциональность таких контейнеров, как массивы, списки, словари, хэши и т.п.
Классы пространства System.ComponentModel используются для реализации необходимого поведения компонентов и элементов управления приложения на этапе его разработки и выполнения.
Наше приложение также определяет собственное пространство имен Hello :
Наше приложение содержим в пространстве имен Hello определение только одного класса Form1 :
///
/// Summary description for Form1.
///
public class Form1 : System.Windows.Forms.Form
<
…
>
Наличие подобных комментариев упрощает документирование проекта.
///
/// Required designer variable.
///
private System.ComponentModel.Container components = null;
Оно представляет собой контейнер, предназначенный для хранения компонентов, размещаемых в форме. Как Вы увидите дальше, с этим полем работает мастер форм.
public Form1()
<
//
// Required for Windows Form Designer support
//
InitializeComponent();
//
// TODO: Add any constructor code
// after InitializeComponent call
//
>
Мастер проектов добавил в исходный текст конструктора комментарий, в котором говорится, что Вы можете добавить после вызова метода InitializeComponent другой необходимый инициализирующий код.
Деструктор класса Form1 в явном виде отсутствует. Однако для освобождения ресурсов приложения после закрытия формы в этом классе определен метод Dispose :
В автоматически созданном комментарии к методу InitializeComponent говорится о том, что этот метод используется мастером форм, и его не следует модифицировать вручную. В режиме просмотра исходного текста данный блок по умолчанию отображается в свернутом виде (рис. 2-14), но при необходимости его можно развернуть.
Прежде всего, этот метод создает новый контейнер для хранения компонентов, и записывает его в описанное нами ранее поле components :
this.components = new System.ComponentModel.Container();
Далее метод InitializeComponent устанавливает два атрибута формы — ее размер Size и текст заголовка Text :
this.Size = new System.Drawing.Size(300,300);
this.Text = «Form1»;
Так как пока наша форма не содержит никаких элементов управления, на этом инициализация формы будет закончена.
///
/// The main entry point for the application.
///
[STAThread]
static void Main()
<
Application.Run(new Form1());
>
Этот метод играет роль точки входа приложения, с которой и начинается его работа.
Метод Main очень прост. Он состоит всего из одной строки, в которой вызывается метод Application.Run :
В качестве параметра методу Application.Run передается ссылка на новый, только что созданный объект класса Form1 ( т.е. на нашу форму).
В форме нашего первого приложения нет никаких компонентов и элементов управления, поэтому нет и обработчиков событий, создаваемых этими компонентами. Теперь мы немного усовершенствуем приложение, добавив в него кнопку и предусмотрев обработку событий, связанных с этой кнопкой.
В исходном виде главное окно (форма) приложения Hello обладает весьма небольшой функциональностью. Наше первое усовершенствование приложения будет заключаться в добавлении кнопки. Если щелкнуть эту кнопку, которой на экране должно будет появиться простейшее диалоговое окно с сообщением.
Рис. 2-16. Добавление кнопки в форму
Рис. 2-17. Изменение надписи на кнопке
Добавив кнопку и отредактировав надпись, нажмите клавишу F 5 для трансляции и запуска программы. Теперь в окне нашей программы появится кнопка, которую можно нажимать (рис. 2-18).
Рис. 2-18. Работающее приложение с кнопкой
private System.Windows.Forms.Button button1;
#region Windows Form Designer generated code
private void InitializeComponent()
<
this.button1 = new System.Windows.Forms.Button();
//
// button1
//
this.button1.Location = new System.Drawing.Point(200, 16);
this.button1.Name = «button1»;
this.button1.TabIndex = 0;
this.button1.Text = » Сообщение «;
//
// Form1
//
this.AutoScaleBaseSize = new System.Drawing.Size(5, 13);
this.ClientSize = new System.Drawing.Size(292, 273);
this.Controls.AddRange(new System.Windows.Forms.Control[] <
this.button1>);
this.Name = «Form1»;
this.Text = «Form1»;
this.button1 = new System.Windows.Forms.Button();
После этого начинается процесс размещения кнопки на поверхности формы.
Этот процесс начинается с вызова метода SuspendLayout :
Это делается для временного отключения механизма генерации сообщений, связанных с размещением элементов в окне формы. Такое отключение позволяет снизить непроизводительные затраты ресурсов процессора при размещении в форме нескольких компонентов сразу.
После того как все необходимые компоненты будут размещены, механизм генерации упомянутых выше сообщений включается снова при помощи метода ResumeLayout :
В промежутке между вызовами методов SuspendLayout и ResumeLayout программа добавляет и размещает элементы управления, а также настраивает их свойства.
Первым делом в форму добавляется наша кнопка:
this.button1.Location = new System.Drawing.Point(200, 16);
Далее программа устанавливает свойства кнопки:
this.button1.Name = «button1»;
this.button1.TabIndex = 0;
this.button1.Text = » Сообщение «;
Свойство Name хранит идентификатор кнопки. При необходимости этот идентификатор можно отредактировать в окне, показанном на рис. 2-17.
После добавления кнопки и настройки ее свойств метод InitializeComponent задает свойства самой формы:
this.AutoScaleBaseSize = new System.Drawing.Size(5, 13);
this.ClientSize = new System.Drawing.Size(292, 273);
this.Controls.AddRange(
new System.Windows.Forms.Control[]
<
this.button1
>
);
Свойство AutoScaleBaseSize задает базовые размеры, которые используются формой для автоматического масштабирования. При этом за основу берется размер системного шрифта.
При помощи свойства ClientSize программа определяет размеры так называемой клиентской области окна ( client area ) нашей формы. Эта область не включает в себя заголовок окна, рамку и полосы прокрутки.
this.Name = «Form1»;
this.Text = «Form1»;
Первое из них задает имя (идентификатор) формы, а второе — текстовую строку, отображаемую в заголовке формы.
Заметьте, что мы сделали лишь несколько движений мышью, добавив кнопку в окно формы. При этом мастер форм автоматически добавил весь код, необходимый для создания и размещения кнопки.
Хотя в усовершенствованной версии приложения есть кнопка, она не несет никакой полезной нагрузки. Теперь нашей задачей будет создание для этой кнопки обработчика события. Когда пользователь щелкает кнопку мышью, этот обработчик должен будет выводить на экран компьютера диалоговое окно с сообщением.
private void button1_Click(object sender, System.EventArgs e)
<
Пока этот метод, получающий управление при щелчке кнопки, ничего не делает, однако мы скоро изменим данное обстоятельство.
Метод button 1_ Click — это обработчик события, возникающего, когда пользователь щелкает кнопку. Чтобы этот метод заработал, его нужно подключить на этапе инициализации формы. Такое подключение обеспечивает следующая строка, добавленная дизайнером формы в метод InitializeComponent :
this.button1.Click += new System.EventHandler(this.button1_Click);
Чтобы в процессе обработки сообщения от кнопки вывести на экран сообщение, измените исходный текст метода button 1_ Click следующим образом:
Рис. 2-19. Диалоговое окно с сообщением
Один из часто применяемых способов отладки программ заключается в их пошаговом выполнении. При этом отладчик выполняет программу построчно, предоставляя на каждом шаге возможность просмотра и редактирования содержимого переменных и других объектов программы.
Клавиша F 11 предназначена для пошагового выполнения программ с входом в тело методов и функций. Что же касается клавиши F 10, то она тоже нужна для пошагового выполнения программ, но при ее использовании вход в тело методов и функций не выполняется.
Таким образом, если нужно отладить функцию, то ее вызов следует выполнить клавишей F 11, а если функция должна быть выполнена без отладки, — то клавишей F 10.
Рис. 2-20. Запуск программы в режиме пошаговой отладки
Рис. 2-21. Отладка конструктора Form1
Теперь если нажать кнопку F 10, метод InitializeComponent будет выполнен без отладки. При помощи кнопки F 11 Вы сумеете отладить строки метода InitializeComponent в пошаговом режиме.
Чтобы отладить обработчик события, необходимо установить так называемую точку остановки ( breakpoint ). Для этого щелкните левой клавишей мыши в узкое вертикальное поле слева от той строки кода, на которой нужно установить точку останова. После этого строка будет выделена красно-кирпичным цветом, а слева напротив нее появится жирная точка (рис. 2‑22).
Рис. 2-22. Установка точки останова
Таким способом Вы можете установить в своей программе несколько точек останова.
Чтобы убрать точку останова, щелкните жирную точку, отмечающую строку программы, еще раз.
Точки останова удобно использовать и для отладки программ, содержащих циклы. Если в цикле делается много итераций, то его прохождение в пошаговом режиме может отнять слишком много времени. Выход простой — установите точку останова после цикла и продолжите работу программы без отладки.
Рис. 2-23. Просмотр содержимого переменных и полей
В левой части этой вкладки находится дерево объектов программы. Раскрывая его ветви, Вы можете получить доступ ко всем необходимым Вам переменным и полям.
Вкладка Autos (рис. 2-24) удобна для контроля текущих изменений значений в полях и переменных.
Рис. 2-24. Вкладка Autos
На этой вкладке автоматически появляются те поля и переменные, значения которых были изменены в результате выполнения текущей строки кода. При этом новые значения выделяются красным цветом.
Рис. 2-25. Вкладка Watch
Другая очень удобная возможность просмотра содержимого полей и переменных предоставляется в окне редактирования исходного текста программы. Если Вам нужно узнать содержимое переменной или поля, установите на нее курсор мыши. Через некоторое время около курсора появится необходимое содержимое, выделенное тонкой рамкой (рис. 2-26).
Рис. 2-26. Просмотр значений полей в редакторе исходного текста
Рис. 2-27. Окно QuickWatch
Здесь, пользуясь деревом полей выбранного Вами объекта, можно просмотреть и, при необходимости, изменить значение полей.
Визуальное проектирование приложений c
Рисование закрашенного сплайна
Рисование закрашенной области типа Region
Пример использования метода FillEllipse мы приводили ранее в разделе «Рисование в окне элемента управления» этой главы. Вот еще один пример:
Однако прежде чем мы займемся рисованием, необходимо сделать маленькое отступление и рассказать о ресурсах приложения.
Если Вы раньше создавали приложения Microsoft Windows, то знаете, что формат загрузочного модуля таких приложений сложнее формата загрузочного модуля программ MS-DOS. Кроме выполняемого кода и констант в загрузочном модуле приложения Microsoft Windows находятся дополнительные данные — ресурсы.
Приложение Microsoft Windows может хранить в виде ресурсов текстовые строки, значки, курсоры, графические изображения, меню, диалоговые окна, произвольные массивы данных и т. д. Физически ресурсы находятся внутри exe-файла приложения. Они могут загружаться в оперативную память автоматически при запуске приложения или по запросу приложения (явному или неявному). Такой механизм обеспечивает экономное использование оперативной памяти, так как все редко используемые данные можно хранить на диске и загружать в память только при необходимости.
Например, приложение может иметь сложную систему диагностики ошибочных ситуаций, содержащую различные диалоговые окна, массивы сообщений об ошибках и т. п. Когда приложение работает без ошибок (что, очевидно, является нормальным явлением) ненужные диагностические ресурсы спокойно лежат на диске, не перегружая оперативную память. Но как только возникает ошибка, и приложение вызовет функцию обработки ошибки, эти ресурсы будут автоматически загружены.
Ресурсы можно редактировать без повторной трансляции программного проекта. Это означает, что Вы сможете легко перевести все сообщения и тексты меню приложения на другой национальный язык, отредактировать графические изображения или любые другие ресурсы, даже не имея в своем распоряжении исходные тексты.
Если приложение должно рисовать в своих окнах значки или графические изображения, целесообразно включить их в ресурсы приложения. В этом случае данные из файлов, содержащих значки или изображения, будут переписаны в файл сборки приложения. Таким образом, Вы сможете поставлять приложение как единый загрузочный файл, не «комплектуя» его дополнительно файлами графических изображений.
Щелкните этот файл левой клавишей мыши, а затем установите значение свойства Build Action для файла значка равным Embedded Resource (рис. 10-18).
Рис. 10-18. Включение значка в ресурсы приложения
В результате выполнения этих действий файл значка (в нашем случае это был файл FACE 02. ICO ) будет добавлен в ресурсы приложения.
Что же касается второго параметра, то через него мы передаем имя ресурса, которое в нашем случае будет совпадать с именем файла значка.
Функция DrawIcon рисует значок myIcon в точке, где был курсор мыши в момент щелчка (рис. 10-19).
Рис. 10-19. Использование метода DrawIcon
Всего существует два перегруженных метода DrawIcon :
public void DrawIcon(Icon, Rectangle);
public void DrawIcon(Icon, int, int);
В первом варианте метода параметр типа Rectangle задает прямоугольную область, внутри которой будет нарисован значок. При этом значок будет масштабирован таким образом, чтобы занять собой всю заданную область.
g.DrawIcon(myIcon, new Rectangle(0, 0, 100, 100));
Если исходный значок меньше указанных размеров, при рисовании он будет растянут, а если больше — сжат.
Для рисования значков можно также использовать метод DrawIconUnstretched :
public void DrawIconUnstretched(Icon, Rectangle);
В ОС Microsoft Windows используются два формата изображений — аппаратно-зависимый DDB ( D evice- D ependent B itmap) и аппаратно-независимый DIB ( D evice- I ndependent B itmap).
Согласно определению, данному в документации, изображение DDB есть набор битов в оперативной памяти, который может быть отображен на устройстве вывода (например, выведен на экран видеомонитора или распечатан на принтере). Внутренняя структура изображения DDB жестко привязана к аппаратным особенностям устройства вывода. Поэтому представление изображения DDB в оперативной памяти полностью зависит от устройства вывода. Иногда такие изображения называют растровыми, подчеркивая тот факт, что их можно рассматривать как совокупность строк растра (горизонтальных линий развертки).
Если бы в Microsoft Windows можно было работать только с изображениями DDB, было бы необходимо иметь отдельные наборы изображений для каждого типа видеоадаптера и каждого видеорежима, что, очевидно, крайне неудобно.
Аппаратно-независимое изображение DIB содержит описание цвета пикселов изображения, которое не зависит от особенностей устройства отображения. ОС Microsoft Windows после соответствующего преобразования может нарисовать такое изображение на любом устройстве вывода. Несмотря на некоторое замедление процесса вывода по сравнению с выводом изображений DDB, универсальность изображений DIB делает их весьма привлекательными для хранения изображений.
Сравнивая эти форматы, отметим, что каждый из них имеет свои преимущества и свои недостатки.
Растровые изображения, как правило, выводятся на экран быстрее, так как их внутренняя структура аналогична (до некоторой степени) структуре видеопамяти. К недостаткам растровых изображений можно отнести большой объем памяти, требующийся для их хранения (которых доходит до десятков и сотен Мбайт), невозможность масштабирования без потери качества изображения, а также сложность выделения и изменения отдельных объектов изображения.
Таблица 10-4. Доступные форматы графических файлов
Растровые изображения DIB (Device-Independent Bitmap)