Многодокументный интерфейс (MDI)
Во многих приложениях Windows вы можете одновременно работать с несколькими документами и одновременно видеть их на экране, каждый – в своем окне. Все эти окна не обладают полной свободой на экране, а находятся внутри главного окна приложения. Они не могут выходить за его пределы. Каждое окно на этапе проектирования было отдельной формой. Для создания таких приложений VB предлагает специальный инструмент – так называемый многодокументный интерфейс – MDI.
Задача: Давайте создадим приложение следующего вида (см. Рис. 27.5).
Рис. 27.5
Оно должно уметь делать следующие вещи:
При выборе пункта меню «Создать новый документ» внутри окна приложения должно создаваться очередное окно документа с заголовком «Документ № …» аналогично тому, как это делается в Microsoft Word. Окон может быть создано сколько угодно.
В окна можно вводить текст.
При выборе пункта меню «Крась» активное окно (то, в котором текстовый курсор) окрашивается в желтый цвет.
При выборе пункта меню «Выравнивай размеры окон» все окна приобретают ширину=200 и высоту=150.
Решение. Создайте проект из двух форм. Форма Form1 будет главным окном приложения, Form2 – образцом для создания окон документов.
Чтобы главное окно приложения могло включать в себя окна документов так, как это показано на рисунке, установите в True свойство IsMdiContainer формы Form1.
Чтобы в окна документов можно было вводить текст, поместите на Form2 текстовое поле, сделайте его многострочным (свойство Multiline = True) и растяните на всю форму. Чтобы при растяжении окна поле растягивалось вместе с ним, придайте его свойству Anchor значение (Top, Bottom, Left, Right).
Мы могли бы поместить на Form1 кнопки, но тогда бы они были видны в главном окне приложения, а это не принято. Вместо этого создайте меню, как мы его видим на рисунке, и введите в окно кода формы Form1 такой текст:
Dim Форма As New Collection
Private Sub MenuItem2_Click(ByVal sender As Object, ByVal e As EventArgs) Handles MenuItem2.Click
Dim Ф As New Form2
Static Счетчик As Integer
Счетчик = Счетчик + 1
Ф.Text = "Документ №" & Счетчик
Форма.Add(Ф)
Ф.MdiParent = Me
Ф.Show()
End Sub
Private Sub MenuItem3_Click( ByVal sender As Object, ByVal e As EventArgs) Handles MenuItem3.Click
Dim Объект As Form2 = Me.ActiveMdiChild
If Not Объект Is Nothing Then Объект.TextBox1.BackColor = Color.Yellow
End Sub
Private Sub MenuItem4_Click(ByVal sender As Object, ByVal e As EventArgs) Handles MenuItem4.Click
Dim i As Integer
For i = 0 To Me.MdiChildren.GetUpperBound(0)
Me.MdiChildren(i).Width = 200
Me.MdiChildren(i).Height = 150
Next
End Sub
Запустите проект и проверьте, как он работает.
Пояснения:
Создаем окно. Процедура создания нового окна (MenuItem2_Click) очень напоминает соответствующий код, используемый при работе с коллекцией форм из предыдущего раздела. Первый оператор создает очередное окно. Следующие три оператора заняты заголовком окна, в частности тем, чтобы там появился нужный номер. Следующий оператор добавляет созданное окно в коллекцию, чтобы впоследствии к нему можно было обращаться.
Следующий оператор
Ф.MdiParent
= Me
объясняет, какое окно для созданного окна является «родительским», то есть внутри какого окна созданное окно должно находиться. Указывает это свойство MdiParent созданного окна. Его значением является ссылка на «родительское» окно. Поскольку «родительским» окном является Form1, то мы можем смело написать Me.
Последний оператор показывает созданное окно на экране.
Красим. Поговорим о процедуре окраски активного окна (MenuItem3_Click). Не забывайте, что красить надо не форму, а текстовое поле. У главного окна многодокументного приложения есть свойство ActiveMdiChild, которое указывает на то из окон, которое в данный момент активно. Но было бы ошибкой решить дело оператором
ActiveMdiChild.TextBox1.BackColor = Color.Yellow
Дело в том, что свойство ActiveMdiChild имеет тип Form, а значит не обладает всем богатством свойств формы Form2. Попросту, оно «не знает», что на форме Form2 есть текстовое поле.
Результата можно добиться парой операторов:
Dim Объект As Form2 = Me.ActiveMdiChild
Объект.TextBox1.BackColor = Color.Yellow
Вдумчивый читатель сморщится при виде первого оператора. Не буду говорить, почему.
У второго оператора есть недостаток. Когда в приложении нет активных окон (предположим, все закрыты), он, естественно, дает ошибку. Надо в этом случае предотвратить его выполнение. Здесь нам поможет тот очевидный факт, что при отсутствии активных окон значение свойства ActiveMdiChild равно Nothing. Это и дает нам окончательный код:
Dim Объект As Form2 = Me.ActiveMdiChild
If Not
Объект Is Nothing Then Объект.TextBox1.BackColor = Color.Yellow
Выравниваем. Поговорим о процедуре выравнивания размеров (MenuItem4_Click). У главного окна многодокументного приложения есть свойство MdiChildren, которое представляет собой массив созданных окон. Массив этот заполняется автоматически, безо всяких усилий с нашей стороны. Получается, что коллекцию мы создавали зря? Я думаю, вы сами ответите на этот вопрос, когда дело дойдет до реальных проектов. Заметьте, кстати, что элементы этого массива тоже имеют тип Form. Остается напомнить, что GetUpperBound(0) – это свойство одномерного массива, равное верхней границе его индекса.