Элементы
меню и новый редактор меню Visual Studio
Хотя визуальное
конструирование форм в книге почти не рассматривается, мы просто не могли не
упомянуть новый редактор меню. Программисты VB уже давно ждали чего-то подобного.
Впрочем, при всем удобстве нового редактора вы извлечете из него максимум пользы
лишь при полном понимании кода, сгенерированного IDE.
Построить
меню в редакторе меню (Menu Editor) несложно. Сначала с панели элементов на
форму перетаскивается элемент MainMenu; на форме появляется заготовка меню (рис.
8.10).
Теперь можно
переходить к вводу команд меню. При вводе очередной команды в редакторе появляются
поля для ввода следующей команды или команд, находящихся на других уровнях иерархии
меню (рис. 8.11). Чтобы отредактировать команду меню, созданную ранее, достаточно
щелкнуть на ней (для изменения существующих меню щелчок делается на элементе
MainMenu на панели под формой). Порядок команд меню изменяется операциями вырезания/вставки
(эти операции работают даже в главной строке меню). Как и в прежних версиях
VB, перед клавишами ускоренного вызова ставится префикс &. На рис. 8.11
показано меню с клавишей ускоренного вызова и разделительной чертой.
Прежде чем
переходить к коду, сгенерированному для меню на рис. 8.11, необходимо знать,
что меню формы инкапсулируется в классе System.Windows.Forms.MainMenu. Объект
MainMenu выполняет функции контейнера для экземпляров Menu Item. Для организации
подменю в экземплярах Menultem определяется свойство Menultems; значение этого
свойства представляет собой коллекцию класса Menu.MenuItemCollection, содержащую
другие объекты Menultem.
Что касается
кода, соответствующего рис. 8.11, то он начинается с объявления команд меню.
Имена, принятые по умолчанию, были заменены более содержательными: вместо Menulteml
используется имя mnuFile и т. д.
Рис.
8.10. Начало построения меню в редакторе меню
Рис.
8.11. Построение меню в новом редакторе меню Visual Studio
Friend WithEvents MainMenul As System.Windows.Forms.MainMenu
Friend WithEvents mnuFile As System.Windows.Forms.Menultem
Friend WithEvents mnuEdit As System.Windows.Forms.MenuItem
Friend WithEvents mnuHelp As System.Windows.Forms.Menultem
Friend WithEvents mnuOpen As System.Windows.Forms.Menultem
Friend WithEvents mnuSave As System.Windows.Forms.Menultem
Friend WithEvents
mnuExit As System.Windows.Forms.Menultem
Чтобы
быстро изменить свойство Name команд меню, щелкните на команде правой кнопкой
мыши и выберите в контекстном меню команду Edit Names (завершив редактирование,
выйдите из этого режима при помощи контекстного меню).
Экземпляр
главного меню создается командой, которую IDE включает в метод
InitializeComponent:
Me. MainMenul
=New System. Windows. Forms. MainMenu ()
Следующий
фрагмент создает в методе Initial! zeComponent объекты отдельных команд
меню:
Me.mnuFile =
New System. Windows. Forms. MenuItem()
Me.mnuNew =
New System. Windows. Forms. MenuItem()
Me.mnuOpen =
New System. Windows. Forms. MenuItem()
Как видно
из этого фрагмента, меню File верхнего уровня тоже представлено экземпляром
класса Menultem. Объекты команд включаются в экземпляр Mai nMenu вызовом
метода AddRange класса Menultems. В следующем примере метод AddRange включает
в меню сразу три команды:
Me . Mai nMenul
. Menultems . AddRange( New System . Windows . Forms . Menultem( )
{Me.mnuFile.
Me.mnuEdit, Me.mnuHelp})
Поскольку у объектов отдельных команд тоже имеется свойство Menultems, автоматически сгенерированный код включения команд выглядит практически так же:
Me . mnuFile
. Menu Items . AddRange ( New System . Windows . Forms . Menul tem( )_
{Me.mnuNew.
Me.mnuOpen. Me.mnuExit. Me.mnuSep})
На последнем шаге IDE подключает события Click для команд меню. Сгенерированный код выглядит так:
Private Sub mnuExit_Click(ByVal
sender As System. Object, _
ByVal e As System.
EventArgs)Handles mnuExit. Click
В прежних
версиях VB создавать контекстные меню было неудобно. В .NET контекстное меню
представляется экземпляром класса ContextMenu и редактируется в визуальном режиме.
Чтобы связать контекстное меню с элементом или формой, достаточно задать значение
свойства ContextMenu этого элемента или формы. По стандартам Windows контекстные
меню вызываются щелчком правой кнопки мыши; в .NET это происходит автоматически
благодаря наследованию. Вам не придется программировать событие MouseDown —
поддержка контекстных меню реализована в классе Control , производными от которого
являются формы и элементы. При перетаскивании на форму элемента ContextMenu
IDE генерирует почти такой же код, как для команд главного меню:
Friend WithEvents
ContextMenul As System.Windows.Forms.ContextMenu
Me.ContextMenul =New System,Windows.Forms.ContextMenu()
Так же вызывается
метод AddRange:
Me.ContextMenul.MenuIterns.AddRange(New
System.Windows.Forms.MenuItem() {Me.MenuIteml})
Чтобы быстро
задать значение свойства Name команд контекстного меню, перейдите в режим редактирования
имен щелчком правой кнопкой мыши.
Поскольку
обычные и контекстные меню управляются на программном уровне, ваше приложение
может построить меню с нуля на стадии выполнения программы!
В прежних
версиях VB при программировании приложений с интерфейсом MDI (Multiple Document
Interface) родительская форма MDI выбиралась на стадии конструирования. В .NET
эта задача решается иначе — свойству IsMdiContainer формы задается значение
True. Программист создает дочерние формы MDI на стадии конструирования или выполнения,
а затем заносит в их свойство Mdi Parent ссылку на форму со свойством I sMdi
Conta i пег, равным True. Таким образом, в программах VB .NET можно сделать
то, что было практически нереально в предыдущих версиях VB, — изменять связи
MDI во время работы программы. Кроме того, приложение может содержать несколько
родительских форм MDI; в VB6 такая возможность не поддерживалась.
Рассмотрим
пример. Создайте приложение со следующей процедурой Forml_Load:
Private Sub Forml_Load(ByVal sender As System.Object._
ByVal e As System.EventArgs)
Handles MyBase.Load
Me.Text = "I'm
an MDI Parent"
Me.IsMdiContainer
- True
Dim MyChild
As New System.Windows.Forms.Form()
MyChiId.MdiParent
= Me
MyChild.Show()
MyChild.Text
="MDI Child" End Sub
Примерный
вид окна показан на рис. 8.12.
Конечно,
это весьма жалкое подобие приложения MDI. В приложениях MDI обычно присутствует
меню Window, позволяющее расположить открытые дочерние окна «черепицей»
или «мозаикой», а также активизировать любое дочернее окно. Меню
Window реализуется в родительском окне, причем его код может быть достаточно
простым:
Public Sub InitializeMenu()
Dim mnuWindow As New MenuItem("&Window")
MainMenu1.MenuIterns.Add(mnuWindow)
mnuWindow.MenuItems.AddCNew
Menultem _
("&Cascade", AddressOf WindowCascade_Clicked))
mnuWindow.MenuItems.Add(New
Menultem
("Tile &Horizontal", AddressOf WindowTileHoriz_C1icked))
mnuWindow.MenuItems.Add(New
Menultem _
("Tile &Vertical". AddressOf WindowTileVert_Clicked))
mnuWindow.MdiList = True
End Sub
Protected Sub WindowCascade_Clicked(ByVal
Sender As Object.
ByValeAs System.EventArgs)
Me.LayoutMdi(MdiLayout.Cascade)
End Sub
Protected Sub WindowTileHoriz_Clicked(ByVal Sender As Object._
ByVal e As System.EventArgs)
Me.LayoutMdi(MdiLayout.TileHorizonta1)
End Sub
Protected Sub WindowTileVert_Clicked(ByVal Sender As Object,
ByVal e As System.EventArgs)
Me.LayoutMdi(MdiLayout.TileVertica1)
End Sub
Примерный
вид окна, полученного при вызове InitializeMenu для формы из предыдущего примера,
показан на рис. 8.13.
Рис.
8.12. Простейшее приложение MDI
Рис.
8.13. Типичное меню Window в приложении MDI
Чтобы оповестить
родительскую форму об активизации дочернего окна, следует зарегистрировать обработчик
для события mdi ChildActivate. Активизируемое окно определяется при помощи свойства
ActiveMdiChild класса Form. Например, в следующем фрагменте создается обработчик
для вывода в строке состояния (элемент StatusBar) родительской формы содержимого
заголовка дочернего окна: AddHandler Me.MdiChi1dActivate.AddressOf Me.MdiChi1dActivated
Остается лишь определить следующую процедуру:
Protected Sub
MdiChi1dActivated(sender As object, e As System.EventArgs)
If (Me.ActiveMdiChild <> Nothing) Then statusBarl.Text
Me.ActiveMdiChild.Text
End If
End Sub
Диалоговые
формы и диалоговые окна
В .NET Framework
включена поддержка стандартных диалоговых окон; соответствующие элементы расположены
в нижней части панели элементов (рис. 8. 14).
Рис.
8.14. Стандартные диалоговые окна на панели элементов
Элементы
диалоговых окон обладают различными свойствами, управляющими их поведением.
Например, у диалоговых окон открытия/сохранения файлов имеется свойство Filter.
В этом разделе рассматриваются лишь основные принципы использования этих полезных
элементов. Полная информация об их свойствах приведена в электронной документации
.NET.
Диалоговые
окна печати описаны в разделе «Печать» настоящей главы.
Классы всех
стандартных диалоговых окон являются производными от абстрактного класса CommonDialog.
Важнейший метод этого класса ShowDialog предназначен для отображения диалогового
окна. По возвращаемому значению этого метода можно узнать, какую кнопку нажал
пользователь в диалоговом окне — ОК или Cancel. Метод ShowDialog имеет следующий
синтаксис: Public Function ShowDialogO As DialogResult
При проверке
возвращаемое значение сравнивается с константами DialogResult .ОК и DialogResult.Cancel.
При использовании
диалогового окна выбора цвета (Col orDialog) программа обычно запрашивает свойство
Color и назначает его свойству ForeColor или BackColor элемента или формы. Например,
приведенная ниже процедура изменяет фоновый цвет формы при нажатии на кнопку:
Private Sub btnCo1or_Click(ByVal sender As System.Object. _
ByVale As System.EventArgs)Handles btnColor.Click
Dim myDialog As New ColorDialog()
Dim Temp As Color = btnColor.BackColor
If myDialog.ShowDialog() = DialogResult.OK Then
Me.BackColor = myDialog.Color btnColor.BackColor = Temp
End If
End Sub
На экране
появляется стандартное диалоговое окно, в котором выбирается нужный цвет.
Диалоговое
окно выбора шрифта (FontDialog) хорошо знакомо всем пользователям текстовых
редакторов Windows. В свойстве Font объекта диалогового окна возвращается объект
Font, обычно назначаемый свойству Font элемента или формы. В следующем примере
предполагается, что на форме находится текстовое поле TextBoxl и кнопка Buttonl:
Private Sub Buttonl_Click_l(ByVal sender As System.Object. _
ByVal e As System.EventArgs)
Handles Buttonl.Click
Dim myDialog
As New FontDialog()
If myDialog.ShowDialog() = DialogResult.OK Then TextBoxl.Font
myDialog.Font
End If
End Sub
(обратите
внимание, как однострочное текстовое поле автоматически подстраивается под размеры
нового шрифта).
Абстрактный
класс FileDialog является базовым для двух специализированных подклассов:
Рассмотрим
использование этих диалоговых окон на простом примере. Элемент RichTextbox .NET,
как и его аналоги из предыдущих версий VB, поддерживает методы LoadFilе и SaveFile
для быстрого открытия и сохранения файлов. Чтобы пример стал более реалистичным,
свойство Filter диалогового окна будет ограничивать вывод файлов .txt и .rtf
(в следующем фрагменте эта строка выделяется жирным шрифтом). Также обратите
внимание на то, как при вызове метода LoadFi 1е указывается текстовый формат
файла (при загрузке файлов RTF второй параметр указывать не обязательно):
Private Sub mnuOpen_Click(ByVal sender As System.Object,_
ByVal e As System.EventArgs)Handles mnuOpen.Click
Dim myDialog As New OpenFileDialog()
myDialog.Filter = "text (*.txt),RTF (*.rtf)|*.txt:*rtf"
If myDialog.ShowDialog
=DialogResult.OK Then
' При загрузке текстовых файлов во втором параметре
' необходимо передавать признак типа файла.
Dim Temp As String = myDialog.FileName.Tollpper
If Temp.EndsWith("TXT")
Then
RichTextBoxl.LoadFi1e(myDialog.FileName,
Ri chTextBoxStreamType.Plai
nText) Else
Ri chTextBoxl.
LoadFiletmyDialog.File_Name.
Ri ChTextBoxStreamType.RichText)
End If
End If End Sub