Создание многооконных приложений

Microsoft Visual Studio 2005 позволяет создавать две разновидности многооконных приложений: SDI - и MDI -приложения. SDI –приложения состоят из нескольких независимых форм (окон). По умолчанию будет создано SDI –приложение. В MDI-приложении имеется одна главная форма, остальные формы находятся в пределах главной; из главной формы можно управлять подчиненными формами. Единственное меню MDI -приложения находится в главном окне.

Перед созданием многооконных приложений его необходимо проектировать: продумать вопрос о том, какие окна нужны и что на них будет отображено. Форма – это разновидность класса. Экземпляры классов, как известно, необходимо создавать. Это правило распространяется и на формы: автоматически создается лишь одна форма – главная. Создание всех остальных форм лежит на программисте. Закрытие формы функцией Close(); или нажатием на кнопку ´ вызывает уничтожение формы и в случае необходимости она должна быть создана заново.

В принципе, любую задачу можно решить как с помощью SDI –приложения, так и с помощью MDI –приложения. Пожалуй, создание SDI –приложения проще. MDI –приложение можно рекомендовать при необходимости создать и работать одновременно с несколькими одинаковыми формами. Сам Microsoft Visual Studio 2005 является SDI –приложением.

4.5.1. Создание SDI –приложения

Пусть наше приложение содержит следующие формы:

- Главная форма с меню.

- Форма для определения режимов работы программы.

- Форма «О программе» (About).

- Форма для ввода исходных данных и вывода результата.

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

Пусть меню имеет следующую структуру:

File Windows Help

Quit New About

Open Dialog

Главная форма содержит только меню и поэтому она здесь не приводится. Форма для определения режимов работы (Form2) программы приведена на рис. 4.4.

Создание многооконных приложений - student2.ru

Рис. 4.4

Две радиокнопки имеют имена rB1 и rB2; две кнопки выбора имена cB1 и cB2; строка редактирования textBox1. Реализация единственной командной кнопки: Hide(); (убрать с экрана, но не уничтожить, в таком случае ее можно позже только открыть, нет необходимости ее заново создавать).

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

1. Во избежание случайного закрытия этой формы уберем с нее кнопку ´ .Для этого дадим ее свойству ControlBox значение False. В нашем приложении мы предусмотрим толькооткрытие этой формы во время работы приложения. Ее создание выполняется автоматически при запуске. Поэтому при случайном ее закрытии (с уничтожением) пользователь лишен возможности ее заново создать.

2. Необходимо обеспечить доступ к радиокнопкам, кнопкам выбора и строке редактирования извне. По умолчанию они имеют атрибут доступа private и являются переменными своего класса (в нашем случае Form2). Для этого их свойствам Modifiers дадим значение public.

3. Желаемое местоположение формы обеспечивается изменением значений двух ее свойств: для StartPosition выберем значение Manual и для Location задаем подходящие значения координат X и Y верхнего левого угла. Таким образом можем подбирать местоположение любой формы, в том числе и главной.

4. Для обеспечения создания и открытия формы при запуске приложения в класс главной формы внести следующие дополнения:

- Объявление Form2 f2; в раздел переменных.

- В конструктор Form1 добавить

public Form1()

{

InitializeComponent();

f2 = new Form2();

F2.Show();

}

5. Реализация пункта меню Open Dialog: f2.Show();

Для создания формы «О программе» используем заготовку: ставим курсор мыши на имя нашего приложения, нажмем правую клавишу, из выпадающего меню выберем Add – New Item, затем из списка About Box и нажмем на кнопку Add. На экране появится заготовка формы «О программе». На ней имеются компоненты типа Label, поэтому внесение изменений в заготовку не вызывает трудностей. Реализация единственной кнопки этой формы Close(); реализация пункта меню About:

private void aboutToolStripMenuItem_Click(object sender, EventArgs e)

{

AboutBox1 ab1;

ab1 = new AboutBox1();

Ab1.ShowDialog();

}

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

Внешний вид формы (Form3) для ввода исходных данных и вывода результата показан на рис. 4.5. Для ввода одномерного массива используем строку. При работе с этой формой необходимо ссылаться на переменные диалоговой формы (Form2). Но они являются переменными другого класса, поэтому ссылка на них возможно только через указатель на экземпляр соответствующего класса. Для обеспечения такой ссылки включим в число переменных Form2:

public Form2 f22;

Реализация пункта меню New:

private void newToolStripMenuItem_Click(object sender, EventArgs e)

{

Form3 f3;

f3 = new Form3();

f3.f22 = f2; //для обеспечения ссылки на диалоговое окно

f3.Show();

}

Создание многооконных приложений - student2.ru

Рис. 4.5

Реализация командной кнопки «Вычислить» (в зависимости от состояния кнопок выбора вычисляют или нет сумму/произведение; в зависимости от состояний радиогруппы обрабатывают числа больше/меньше заданного в диалоговом окне значения):

private void button2_Click(object sender, EventArgs e)

{

string[] St1Arr;

string r1;

double []x;

double z,sum = 0,pr = 1;

r1 = textBox1.Text;

St1Arr = r1.Split(';');

x = new double[St1Arr.Length];

z=Convert.ToDouble(f22.textBox1.Text);

for (int i = 0; i < x.Length; i++)

x[i] = Convert.ToDouble(St1Arr[i]);

if (f22.cB1.Checked)

//найдем сумму, используем ссылку на диалоговую форму

{

for (int i = 0; i < x.Length; i++)

{

if (f22.rB1.Checked && x[i] >= z) sum += x[i];

if (f22.rB2.Checked && x[i] < z) sum += x[i];

}

}

if (f22.cB2.Checked) //найдем произведение

{

for (int i = 0; i < x.Length; i++)

{

if (f22.rB1.Checked && x[i] >= z) pr*= x[i];

if (f22.rB2.Checked && x[i] < z) pr*= x[i];

}

}

label3.Text = "" + sum;

label5.Text = "" + pr;

}

4.5.2. Создание MDI –приложения

В MDI –приложении существует одна главная форма и множество подчиненных. Чтобы окно Form1 стала главным, поменяем значение его свойства IsMdiContainer на True. Разрешается и создание окон, которые открывают из главного окна, но не являются подчиненными. Но такими окнами нельзя управлять из главного окна. В нашем приложении будут:

- Главное окно с меню.

- Окно «О программе».

- Динамически создаваемое диалоговое окно.

- Окно, которое можно создавать многократно из главного.

- Окно, которое можно создать из главного в единственном экземпляре.

Убедительно рекомендуем: не размещайте на главном окне ничего, кроме меню! Пусть меню имеет следующую структуру:

Файл Окно Диалог Помощь

Выход Создать Открыть О программе

Каскад

Мозаика горизонтально

Мозаика вертикально

Закрыть текущее

Закрыть все

Единственная форма

Создание окна «О программе» ничем не отличается от рассмотренного выше и мы на этом останавливаться не будем.

Переходим к рассмотрению диалогового окна, которое может создаваться и уничтожаться по ходу работы с программой. (Диалоговое окно, которое существует всегда и которое может лишь появиться на экране и исчезнуть с него, было рассмотрено выше и, таким же образом можно с ним работать и в MDI –приложении). Очевидно, что если диалоговое окно уничтожается, то все его компоненты потеряют свои значения и чтобы этого не случилось, следует их где-то хранить. Мы используем для этого переменные в классе главной формы. Внешний вид диалогового окна приведен на рис. 4.6.

Создание многооконных приложений - student2.ru

Рис. 4.6

Нанесенные на него компоненты нам знакомы, они имеют имена rB1, rB2, cB1, cB2, tB1. У всех атрибут доступа (свойство Modifiers) изменен на public. Кнопки ОК и CANCEL по традиции позволяют закрыть окно с (без) сохранением внесенных изменений. Нам предстоит решить следующие задачи:

- Открыть диалоговое окно с присвоением текущих значений его компонентам.

- Работа с диалоговым окном.

- Закрытие окна с сохранением, в случае необходимости, внесенных изменений.

Для хранения внесенных в диалоговое окно значений в то время, когда само окно не существует, объявим в классе главного окна (у нас Form1) следующие переменные:

static public int rgi;//для хранения номера выбранной радиокнопки

static public Boolean b1,b2;//для кнопок выбора

static public string s1; // для строки редактирования

Атрибут доступа public необходим, чтобы можно из диалогового окна к ним обращаться. Атрибут static позволяет ссылаться на эти переменные через имя класса.

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

private void Form1_Load(object sender, EventArgs e)

{

rgi = 0;

b1 = false;

b2 = true;

s1 = "I love Moscow";

}

Открытие этого окна (пункт меню Диалог – Открыть):

private void открытьToolStripMenuItem_Click(object sender, EventArgs e)

{

Form2 f2;

f2 = new Form2();

Switch(rgi)

{ case 0:

f2.rB1.Checked=true;

Break;

case 1:

f2.rB2.Checked=true;

Break;

}

f2.cB1.Checked = b1;

f2.cB2.Checked = b2;

f2.tB1.Text = s1;

F2.ShowDialog();

}

Работа с окном ничего нового для нас не содержит, и мы на этом останавливаться не будем.

Закрытие окна кнопкой CANCEL: Close();

Закрытие окна кнопкой OK: сохранение значений и закрытие.

private void button1_Click(object sender, EventArgs e)

{

Form1.s1 = tB1.Text;

Form1.b1 = cB1.Checked;

Form1.b2 = cB2.Checked;

if (rB1.Checked) Form1.rgi = 0;

else Form1.rgi = 1;

Close();

}

Многократно создаваемое окно представлено на рис. 4.7.

Создание многооконных приложений - student2.ru

Рис. 4.7

Создание окна (создавать можно много подобных окон):

private void создатьToolStripMenuItem_Click(object sender, EventArgs e)

{

Form3 f3;

f3 = new Form3();

f3.MdiParent = this;// задаем, что созданное окно

//является подчиненным для окно, из которого оно создано

f3.label1.Text = s1;

F3.Show();

}

Примечание. Использовать для показа подчиненных окон функцию ShowDialog нельзя!

Управление подчиненными окнами осуществляется стандартными средствами

private void каскадToolStripMenuItem_Click(object sender, EventArgs e)

{

this.LayoutMdi(MdiLayout.Cascade); //располагать каскадом

}

private void мозаикаГоризонтальбноToolStripMenuItem_Click(object sender, EventArgs e)

{ // горизонтальная мозаика

Наши рекомендации