Знакомство с Microsoft .NET Framework 2.0
Часть 2. Windows Forms 2.0
Алексей Федоров сотрудник отдела стратегических технологий российского представительства компании Microsoft (alexeif@microsoft.com).
Профессиональные меню, статусные панели и панели инструментов
Компоненты для отображения данных
Компоненты для управления расположением элементов
Редактор с поддержкой шаблонов
Поддержка асинхронных операций
Улучшения в поддержке вывода на устройства печати
предыдущем номере журнала мы начали знакомство с новой версией платформы Microsoft .NET. Были рассмотрены основные изменения и дополнения в библиотеке классов и выделены основные функциональные группы, к которым эти изменения относятся. В данной статье мы более подробно поговорим об изменениях в библиотеке классов, относящихся к созданию Windows-приложений. Эта область библиотеки классов содержит пространство имен System.Windows.Forms, в котором определены собственно формы, базовые и расширенные интерфейсные элементы, компоненты и стандартные диалоговые панели, а также подчиненные пространства имен, отвечающие за более специфические операции, а именно:
• дизайнеры Visual Studio (System.Windows.Forms.Design);
• расположение элементов (System.Windows.Forms.Layout);
• вывод на устройства печати (System.Windows.Forms.Printing);
• поддержка различных стилей визуализации (System.Windows.Forms.VisualSyles).
Знакомство с новинками в Windows Forms мы начнем с обсуждения новых компонентов, используемых для создания интерфейсов Windows-приложений. Данные компоненты можно разделить на следующие группы:
• профессиональные меню, статусные панели и панели инструментов MenuStrip, ContextMenuStrip, StatusStrip, ToolStrip;
• компоненты для отображения данных DataGridView;
• компоненты для управления расположением элементов SplitContainer, FlowLayoutPanel и TableLayoutPanel;
• web-браузер WebBrowser;
• редактор с поддержкой шаблонов MaskedTextBox;
• проигрыватель SoundPlayer.
Профессиональные меню, статусные панели и панели инструментов
ля создания профессиональных интерфейсных элементов Windows-приложений, соответствующих последним требованиям эргономики и схожих с интерфейсными элементами приложений компании Microsoft, предлагается использовать новый набор интерфейсных компонентов, входящих в состав Windows Forms 2.0. К этим компонентам относятся:
• MenuStrip компонент для создания основных меню приложений, который пришел на смену компоненту MainMenu;
• ContextMenuStrip компонент для создания контекстных меню приложений, сменивший компонент ContextMenu;
• StatusStrip компонент для создания статусных панелей, который пришел на смену компоненту StatusBar;
• ToolStrip компонент для создания панелей инструментов, сменивший компонент ToolBar.
Следует отметить, что компоненты MainMenu, ContextMenu, StatusBar и ToolBar по-прежнему поддерживаются (по умолчанию они не отображаются в панели ToolBar Visual Studio 2005) и могут использоваться в Windows Forms 2.0, но для создания более профессиональных интерфейсов рекомендуется применять новые компоненты, которые будут рассмотрены далее.
Поскольку компоненты MenuStrip и StatusStrip являются наследниками компонента ToolStrip, а компонент ContextMenuStrip происходит от наследника компонента ToolStrip ToolStripDropDownMenu, сначала мы рассмотрим компонент ToolStrip.
Пример имитации интерфейса Microsoft Outlook с помощью новых интерфейсных элементов Windows Forms 2.0
Компонент ToolStrip
Данный компонент служит в качестве базового класса для компонентов, реализующих меню и статусные панели, а также для создания панелей инструментов. Создаваемые с помощью компонента ToolStrip панели похожи на инструментальные панели в таких продуктах, как Microsoft Windows XP, Microsoft Office, Microsoft Internet Explorer, и обладают широкими возможностями настройки, включая поддержку визуальных шаблонов (themes), а также поддерживают динамическое изменение расположения элементов.
Компонент ToolStrip может служить контейнером для следующих компонентов:
• ToolStripButton реализует кнопку на инструментальной панели;
• ToolStripComboBox реализует список на инструментальной панели;
• ToolStripSplitButton реализует кнопку-разделитель на инструментальной панели;
• ToolStripLabel реализует элемент инструментальной панели, который может содержать текст, графическое изображение или гиперссылку;
• ToolStripSeparator реализует разделитель на инструментальной панели;
• ToolStripDropDownButton реализует кнопку с раскрытием вложенных элементов на инструментальной панели;
• ToolStripTextBox реализует строку ввода текста на инструментальной панели.
Помимо этого можно использовать компонент ToolStripControlHost для размещения в инструментальной панели любых других компонентов Windows Forms.
Компонент ToolStrip обеспечивает базовую функциональность инструментальных панелей, включая отрисовку элементов, обработку событий от мыши и клавиатуры, поддержку операций drag-and-drop и т.п. Для расширения функциональности панелей инструментов можно воспользоваться классом ToolStripManager, чтобы объединить элементы панели в специальные горизонтальные или вертикальные области (RaftingContainer). Для получения более полного контроля над стилями и отрисовкой панелей можно использовать класс ToolStripRenderer.
Вопросы миграции
При миграции приложений, использующих компонент ToolBar, на применение компонента ToolStrip нужно учитывать следующее:
• требуется заменить ссылку на ToolBar ссылкой на ToolStrip;
• необходимо заменить ссылку на ToolBarButton ссылкой на ToolStripButton, обращая внимание на разделители (ToolStripSeparator);
• у нового компонента отсутствуют свойства DropDownArrows и ShowToolTips;
• при добавлении компонентов ToolStripItems с применением метода AddRange вместо ToolStripButton следует использовать ToolStripItem;
• компоненты ImageLists работают «как есть»;
• требуется переключение обработчиков событий компонент ToolBar использует единый обработчик, тогда как каждый элемент ToolStripButtons имеет свой обработчик события Click.
Теперь обратимся к компонентам, построенным на основе компонента ToolStrip.
Компонент MenuStrip
Компонент MenuStrip представляет собой контейнер для создания структуры меню, каждый элемент которого реализуется с помощью компонента ToolStripMenuItem. Каждый такой элемент может либо представлять конкретную команду, либо содержать дочерние элементы.
Компонент MenuStrip может содержать компоненты ToolStripMenuItem, ToolStripComboBox, ToolStripSeparator и ToolStripTextBox.
Вопросы миграции
При миграции на использование компонента MenuStrip нужно учитывать следующее:
• требуется заменить ссылку на MainMenu ссылкой на MenuStrip;
• требуется заменить ссылку на MenuItems ссылкой на ToolStripMenuItems;
• у нового компонента отсутствует свойство Index;
• компонент MenuStrip должен быть добавлен в коллекцию компонентов формы, а не определен через свойство Menu.
Для создания контекстных меню применяется компонент ContextMenuStrip, который мы рассмотрим в следующем разделе.
Компонент ContextMenuStrip
Данный компонент используется для реализации контекстных меню, которые отображаются, когда пользователь щелкает правой кнопкой мыши по интерфейсному элементу или определенной области формы. Для связи интерфейсных элементов или формы с контекстным меню используется свойство ContextMenuStrip соответствующего элемента или формы.
Контекстное меню может состоять из следующих элементов: ToolStripMenuItem, ToolStripComboBox, ToolStripSeparator и ToolStripTextBox.
Вопросы миграции
При миграции на применение компонента ContextMenuStrip нужно учитывать следующее:
• требуется заменить ссылку на ContextMenu ссылкой на ContextMenuStrip;
• у нового компонента используется коллекция Items, а не MenuItems;
• коллекция ToolStripMenuItems не имеет свойства Index.
Последний интерфейсный элемент, который мы рассмотрим в этом разделе, это компонент StatusStrip.
Компонент StatusStrip
Этот компонент используется для создания статусных панелей и обычно состоит из нескольких элементов StatusStripPanel, добавляемых с помощью метода AddRange, каждый из которых может содержать либо текст, либо графическое изображение, либо и то и другое. Статусная панель также может содержать компоненты ToolStripLabel и ToolStripProgressBar.
Вопросы миграции
При миграции на применение компонента StatusStrip нужно учитывать следующее:
• требуется заменить ссылку на StatusBar ссылкой на StatusStrip;
• заменить StatusBarPanel на StatusStripPanel.
После того как мы рассмотрели компоненты, используемые для создания профессиональных меню, статусных панелей и панелей инструментов, обратимся к компонентам, применяемым для отображения данных.
Компоненты для отображения данных
Компонент DataGridView
Для отображения данных в табличном формате служит компонент DataGridView, который призван заменить функциональность компонента DataGrid из предыдущих версий Windows Forms. Этот компонент может использоваться для представления данных любого объема, доступных либо только для чтения, либо для чтения и редактирования. Данные могут как находиться во внешнем источнике (который задается свойствами DataSource и DataMember), так и добавляться программным образом непосредственно в компонент. При работе с большими объемами данных можно применять свойство VirtualMode для отображения подмножества данных. Использование этого свойства требует реализации операций кэширования данных, которые связываются с компонентом через обработчик события CellValueNeeded.
Компонент DataGridView
Компонент DataGridView поддерживает большое число настроек ячеек, рядов, колонок и рамок вокруг них для этого используется широкий набор свойств, в том числе DefaultCellStyle, ColumnHeadersDefaultCellStyle, CellBorderStyle и GridColor.
Вопросы миграции
При миграции на использование компонента DataGridView рекомендуется полностью изменять дизайн формы с учетом новых возможностей компонента, так как миграция в большинстве случаев может потребовать больших усилий. Если же редизайн по каким-то причинам невозможен, нужно учитывать следующее:
• при простом отображении данных необходимо изменить код, отсылающий на компонент DataGrid, ссылкой на DataGridView;
• при комплексном использовании компонента DataGrid необходимо:
- выполнить вышеописанные действия,
- исправить ошибки, связанные с обращением к отсутствующим свойствам,
- перенастроить стили DataGridView так, чтобы они максимально соответствовали стилям, используемым в DataGrid,
- исправить обработчики событий.
Компонент DataConnector
Новый компонент DataConnector выполняет роль связующего звена между интерфейсным элементом и источником данных. Он автоматически управляет такими функциями, как поддержка текущего состояния, события в источниках данных и изменения источников данных. Помимо обеспечения связи с интерфейсными элементами DataConnector может выполнять функции строго типизированного источника данных.
Компонент DataConnector предназначен для совместного использования с такими компонентами, как DataNavigator и DataGridView.
Компонент DataNavigator
Данный компонент представляет собой стандартную панель для навигации по данным и манипуляции ими. В большинстве сценариев компонент DataNavigator используется совместно с компонентом DataConnector (через свойство DataConnector) для перемещения по записям и выполнения манипуляций над ними.
Предоставляемый по умолчанию интерфейс компонента DataNavigator состоит из серии кнопок, тестовых элементов и надписей, применяемых для выполнения наиболее часто используемых операций с данными: навигации, добавления, удаления, а также для отображения статусной информации.
Компоненты для управления расположением элементов
Windows Forms 2.0 появился ряд расширений, связанных с управлением расположением элементов на форме. К ним относятся некоторые новые свойства компонентов (Margin, Padding, Autosize), а также три новых компонента SplitContainer, FlowLayoutPanel и TableLayoutPanel, которые мы рассмотрим ниже.
Компонент SplitContainer
Данный компонент представляет собой перемещаемую полосу, которая разделяет область контейнера на две панели, размер которых может изменяться. В каждой панели может быть размещен любой компонент Windows Forms, включая и другие компоненты SplitContainer.
Компонент поддерживает вертикальное и горизонтальное разделение панелей и различные настройки, позволяющие управлять шагом перемещения разделительной полосы, минимальными размерами панелей, способами их заполнения, типом рамки вокруг панелей и т.п.
Вопросы миграции
При миграции с компонента Splitter, поддерживавшегося в предыдущих версиях Windows Forms, необходимо изменить тип компонента (со Splitter на SplitContainer), изменить значение свойства Dock компонентов, расположенных внутри панелей, связать эти компоненты с родительским компонентом и, при необходимости, изменить размеры и местоположение компонентов внутри панелей.
Компонент FlowLayoutPanel
Данный компонент представляет собой панель, которая динамически отображает свое содержимое в горизонтальном (FlowDirection = LeftToRight) или вертикальном виде (FlowDirection = TopDown). В панели компонента FlowLayoutPanel могут располагаться любые компоненты Windows Forms, включая и компоненты FlowLayoutPanel.
Компонент TableLayoutPanel
Данный компонент представляет собой панель, которая динамически распределяет свое содержимое, размещенное в ячейках таблицы. В такой таблице может находиться любой компонент Windows Forms, включая и компоненты TableLayoutPanel. В зависимости от значений свойств RowCount, ColumnCount и GrowStyle в компонент могут быть добавлены новые элементы, что приведет к динамическому изменению его размера. Помимо этого можно управлять вертикальным или горизонтальным расширением компонента. Точные настройки рядов и колонок осуществляются с помощью свойств RowStyles и ColumnStyles.
Редактор с поддержкой шаблонов
омпонент MaskedTextBox представляет собой расширенную версию компонента TextBox и позволяет применять описания масок для определения корректности введенной информации.
В случае использования нестандартных масок предполагается использование синтаксиса, схожего с синтаксисом регулярных выражений.
Компонент поддерживает возможность выдачи звукового сигнала в случае неверно введенной информации.
Задание масок в Visual Studio 2005
Более комплексная проверка введенных данных может предполагать сравнение с допустимым значением для конкретного типа данных. Этой цели служит свойство ValidatingType, в котором указывается соответствующий тип данных. В случае успешного завершения проверки возникает событие TypeValidationCompleted; объект с введенным значением становится доступным с помощью свойства ReturnValue, которое можно найти в коллекции TypeValidationEventArgs.
Проигрыватель
омпонент SoundPlayer позволяет реализовать синхронное или асинхронное воспроизведение звука в формате *.wav в приложениях. Файлы могут загружаться либо из встроенного ресурса, либо из файла, либо по протоколу HTTP, либо из потока. Местоположение задается или в конструкторе, или свойствами SoundLocation либо Stream. Файл может быть загружен как до его воспроизведения (методы Load, LoadAsync), так и при вызове одного из методов, воспроизводящих его содержимое (методы Play, PlayLooping, PlaySync).
Завершение загрузки файла приводит к возникновению события LoadCompleted, в обработчике которого можно проверить статус загрузки файла. При изменении местоположения файла возникает событие SoundLocationChanged, а при изменении потока событие StreamChanged.
Отметим, что для воспроизведения системных звуков, определенных типом SystemSounds, не требуется создания экземпляра объекта SoundPlayer: каждый из системных звуков возвращает экземпляр SoundPlayer надо лишь вызвать его метод Play.
Web-браузер
ККомпонент WebBrowser позволяет отображать в Windows-приложениях содержимое Web-страниц. Этот компонент представляет собой «обертку» вокруг соответствующего ActiveX-компонента Internet Explorer и представлен классом System.Windows.Forms.WebBrowser. Компонент WebBrowser может использоваться для реализации справочной системы на основе HTML-документов или для поддержки функций просмотра содержимого Интернета. Помимо этого компонент WebBrowser может применяться для преобразования существующих Web-приложений в клиентские приложения, которые используют DHTML-код для управления пользовательским интерфейсом.
Вместе с компонентом WebBrowser поставляется набор управляемых классов для манипуляции содержимым Web-страниц HTML DOM. Эти управляемые классы не перекрывают на 100% функциональность IE DOM, но позволяют выполнять наиболее часто осуществляемые операции, включая обработку событий непосредственно из управляемого кода. Помимо этого управляемые классы HTML DOM предоставляют доступ к атрибутам HTML-документа, которые недоступны напрямую, для этого используются методы типа GetAttribute (string attributeName).
Поддержка асинхронных операций
Для выполнения операций в отдельном потоке предоставляется класс BackgroundWorker и соответствующий компонент, который можно перетащить на форму из панели компонентов (вкладка Components). Метод DoWork() данного компонента должен содержать код, который будет выполняться в отдельном потоке. По окончании работы метода DoWork() происходит событие RunWorkerCompleted, в обработчике которого можно предусмотреть соответствующие действия. Для отслеживания прогресса выполнения фоновой операции используется обработчик события ProgressChanged.
Для досрочного завершения фоновой операции используется метод CancelAsync, который устанавливает соответствующее значение свойства CancellationPending. Фоновый код, поддерживающий досрочное завершение, проверяет значение этого свойства и, как только оно становится равным True, завершает свое выполнение. Свойство WorkerSupportsCancellation компонента BackgroundWorker должно быть установлено равным True для того, чтобы была обеспечена поддержка досрочного завершения операций.
Отметим, что ряд компонентов Windows Forms теперь поддерживает асинхронные операции. К таким компонентам, в частности, относится рассмотренный выше компонент SoundPlayer и компонент PictureBox, у которого теперь есть метод LoadAsync.
Поскольку фоновая операция выполняется в отдельном потоке, в ее коде не допускаются манипуляции с элементами формы. Это ограничение связано с тем, что обработка сообщений происходит именно в том потоке, в котором изначально создан элемент.
Для решения более широкого круга задач, связанных с выполнением асинхронных операций (например, создания собственных компонентов), можно использовать класс AsyncOperationManager.
Улучшения в поддержке вывода на устройства печати
Поддержка вывода на устройства печати в .NET Framework версий 1.0 и 1.1 была далека от совершенства. Существенные улучшения в этом направлении планируются в .NET Framework 2.0. Новый класс SimplePrintDocument позволяет выполнять вывод на устройства печати с помощью вызова набора простых и интуитивно понятных методов.
После создания нового экземпляра SimplePrintDocument класса пользователь устанавливает значения свойств: размер рабочей области документа, наличие рамок, наличие верхних и нижних колонтитулов, определяет необходимые настройки принтера и т.п., а затем использует методы DrawXXX (для отрисовки графики) или WriteXXX (для вывода текстовой информации) для заполнения распечатываемого документа. Для распечатки таблиц предоставляются методы WriteDataboundTable и WriteDataboundTable, а для распечатки таблиц, связанных с источниками данных, используется метод WriteDataboundTable.
На этом мы завершаем краткое знакомство с новинками в Windows Forms 2.0. В следующем номере мы рассмотрим основные изменения в технологии создания Web-приложений ASP .NET 2.0.