Добавить в цитаты Настройки чтения

Страница 348 из 371

Модальные и немодальные формы

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

Передача информации между формами

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

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

Представим себе, что несколько форм должны работать с объектом класса Books. Пусть в главной форме такой объект объявлен:

public Books myBooks;

В конструкторе главной формы такой объект создается:

myBooks = new Books(max_books);

где max_books — заданная константа. Пусть еще в главной форме объявлена форма — объект класса

NewBook; public NewBook form2;

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

Класс newBook содержит поля:

private Form1 mainform;

private Books books;

а его конструктор следующий код:

mainform = form;

books = mainform.myBooks;

Теперь объекту form2 доступны ранее созданные объекты, задающие книги и главную форму, так что в обработчике события closed, возникающего при закрытии формы, можно задать код:

private void NewBook_Closed(object sender, System.EventArgs e)

{

    mainform.Show();

}

открывающий главную форму.

Образцы форм

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





Главная кнопочная форма

Одним из образцов, применимых к главной форме, является главная кнопочная форма. Такая форма состоит из текстового окна, в котором описывается приложение и его возможности, и ряда командных кнопок-, обработчик каждой кнопки открывает форму, позволяющую решать одну из задач, которые поддерживаются данным приложением. В качестве примера рассмотрим Windows-приложение, позволяющее работать с различными динамическими структурами данных. Главная кнопочная форма такого приложения показана на рис. 24.2.

Рис. 24.2. Главная кнопочная форма

Обработчик события Click для каждой командной кнопки открывает форму для работы с соответствующей динамической структурой данных. Вот как выглядит обработчик события кнопки Список:

private void button4_Click(object sender, System.EventArgs e)

{

   //Переход к показу формы для работы со списком

   FormList f1= new FormList();

   f1.Show();

}

Как видите, открывается новая форма для работы со списком, но главная форма не закрывается и остается открытой.

Шаблон формы для работы с классом

Можно предложить следующий образец формы, предназначенной для поддержки работы с объектами некоторого класса. Напомню, каждый класс представляет тип данных. Операции над типом данных можно разделить на три категории: конструкторы, команды и запросы. Конструкторы класса позволяют создать соответствующий объект; команды, реализуемые процедурами, изменяют состояние объекта; запросы, реализуемые функциями без побочных эффектов, возвращают информацию о состоянии объекта, не изменяя самого состояния. Исходя из этого, можно сконструировать интерфейс формы, выделив в нем три секции. В первой секции, разделенной на три раздела, будут представлены команды, запросы и конструкторы. Следующая секция выделяется для окон, в которые можно вводить аргументы исполняемых команд. Последняя секция предназначается для окон, в которых будут отображаться результаты запросов.

На рис. 24.3 показана форма для списка с курсором, построенная в соответствии с описанным шаблоном.

Рис. 24.3. Форма для списка с курсором, построенная по образцу

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

Работа со списками (еще один шаблон)

Для организации интерфейса разработано большое число элементов управления, часть из них показана на рис. 24.1. Все они обладают обширным набором свойств, методов и событий, их описание может занять отдельную книгу. Такие элементы, как, например, ListView, Treeiew, DataGrid, несомненно, заслуживают отдельного рассмотрения, но не здесь и не сейчас. Я ограничусь более подробным разбором лишь одного элемента управления — ListBox, — позволяющего отображать данные в виде некоторого списка.

Элемент управления класса ListBox

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

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

Давайте рассмотрим главный вопрос: как список заполняется элементами? Есть несколько разных способов. Новой и интересной технологией, применимой к самым разным элементам управления, является связывание элемента управления с данными, хранящимися в различных хранилищах, прежде всего, в базах данных. Для этого у списка есть ряд свойств — DataBinding и другие. Эта технология заслуживает отдельного рассмотрения, я о ней только упоминаю, но рассматривать ее не буду. Рассмотрим три других способа.