Язык программирования C#9 и платформа .NET5 - Эндрю Троелсен
Шрифт:
Интервал:
Закладка:
На заметку! Хотя WPF переносит все запросы визуализации на уровень DirectX, нельзя утверждать, что приложение WPF будет работать настолько же быстро, как приложение, построенное с использованием неуправляемого языка C++ и DirectX. Несмотря на значительные усовершенствования, вносимые в WPF с каждым новым выпуском, если вы намереваетесь строить настольное приложение, которое требует максимально возможной скорости выполнения (вроде трехмерной игры), то неуправляемый C++ и DirectX по-прежнему будут наилучшим выбором.
Упрощение программирования сложных пользовательских интерфейсов
Чтобы подвести итоги сказанному до сих пор: WPF — это API-интерфейс, предназначенный для построения настольных приложений, который интегрирует разнообразные настольные API-интерфейсы в единую объектную модель и обеспечивает четкое разделение обязанностей через XAML. В дополнение к указанным важнейшим моментам приложения WPF также выигрывают от простого способа интеграции со службами, что исторически было довольно сложным. Ниже кратко перечислены основные функциональные возможности WPF.
• Множество диспетчеров компоновки (гораздо больше, чем в Windows Forms) для обеспечения исключительно гибкого контроля над размещением и изменением позиций содержимого.
• Применение расширенного механизма привязки данных для связывания содержимого с элементами пользовательского интерфейса разнообразными способами.
• Встроенный механизм стилей, который позволяет определять "темы" для приложения WPF.
• Использование векторной графики, поддерживающей автоматическое изменение размеров содержимого с целью соответствия размерам и разрешающей способности экрана, который отображает пользовательский интерфейс приложения.
• Поддержка двумерной и трехмерной графики, анимации, а также воспроизведения видео- и аудио-роликов.
• Развитый типографский API-интерфейс, который поддерживает документы XML Paper Specification (XPS), фиксированные документы (WYSIWYG), документы нефиксированного формата и аннотации в документах (например, API-интерфейс Sticky Notes).
• Поддержка взаимодействия с унаследованными моделями графических пользовательских интерфейсов (такими как Windows Forms, ActiveX и HWND-дескрипторы Win32). Например, в приложение WPF можно встраивать специальные элементы управления Windows Forms и наоборот.
Теперь, получив определенное представление о том, что инфраструктура WPF привносит в платформу, давайте рассмотрим разнообразные типы приложений, которые могут быть созданы с применением данного API-интерфейса. Многие из перечисленных выше возможностей будут подробно исследованы в последующих главах.
Исследование сборок WPF
В конечном итоге инфраструктура WPF — не многим более чем коллекция типов, встроенных в сборки .NET Core. В табл. 24.3 описаны основные сборки, используемые при разработке приложений WPF, на каждую из которых должна быть добавлена ссылка, когда создается новый проект. Как и следовало ожидать, проекты WPF в Visual Studio ссылаются на эти обязательные сборки автоматически.
В этих четырех сборках определены новые пространства имен, а также классы, интерфейсы, структуры, перечисления и делегаты .NET Core. В табл. 24.4 описана роль некоторых (но далеко не всех) важных пространств имен.
В начале путешествия по программной модели WPF вы исследуете два члена пространства имен System.Windows, которые являются общими при традиционной разработке любого настольного приложения: Application и Window.
На заметку! Если вы создавали пользовательские интерфейсы для настольных приложений с использованием API-интерфейса Windows Forms, то имейте в виду, что сборки System.Windows.Forms.* и System.Drawing.* никак не связаны с WPF. Они относятся к первоначальному инструментальному набору .NET для построения графических пользовательских интерфейсов, т.е. Windows Forms/GDI+.
Роль класса Application
Класс System.Windows.Application представляет глобальный экземпляр выполняющегося приложения WPF. В нем имеется метод Run() (для запуска приложения) и комплект событий, которые можно обрабатывать для взаимодействия с приложением на протяжении его времени жизни (наподобие Startup и Exit). В табл. 24.5 описаны основные свойства класса Application.
Построение класса приложения
В любом приложении WPF нужно будет определить класс, расширяющий Application. Внутри такого класса определяется точка входа программы (метод Main()), которая создает экземпляр данного подкласса и обычно обрабатывает события Startup и Exit (при необходимости). Вот пример:
// Определить глобальный объект приложения для этой программы WPF.
class MyApp : Application
{
[STAThread]
static void Main(string[] args)
{
// Создать объект приложения.
MyApp app = new MyApp();
// Зарегистрировать события Startup/Exit.
app.Startup += (s, e) => { /* Запуск приложения */ };
app.Exit += (s, e) => { /* Завершение приложения */ };
}
}
В обработчике события Startup чаще всего обрабатываются входные аргументы командной строки и запускается главное окно программы. Как и следовало ожидать, обработчик события Exit представляет собой место, куда можно поместить любую необходимую логику завершения программы(например, сохранение пользовательских предпочтений).
На заметку! Метод Main() приложения WPF должен быть снабжен атрибутом [STAThread], который гарантирует, что любые унаследованные объекты СОМ, используемые приложением, являются безопасными в отношении потоков. Если не аннотировать метод Main() подобным образом, тогда во время выполнения возникнет исключение. Даже после появления в версии C# 9.0 операторов верхнего уровня вы все равно будете стремиться использовать в приложениях WPF традиционный метод Main(). В действительности метод Main() генерируется автоматически.
Перечисление элементов коллекции Windows
Еще одним интересным свойством класса Application является Windows, обеспечивающее доступ к коллекции, которая представляет все окна, загруженные в память для текущего приложения WPF. Вспомните, что создаваемые новые объекты Window автоматически добавляются в коллекцию Application.Windows. Ниже приведен пример метода, который сворачивает все окна приложения(возможно в ответ на нажатие определенного сочетания клавиш или выбор пункта меню конечным пользователем):
static void MinimizeAllWindows()
{
foreach (Window wnd in Application.Current.Windows)
{
wnd.WindowState = WindowState.Minimized;
}
}
Вскоре будет построено несколько приложений WPF, а пока давайте выясним основную функциональность типа Window и изучим несколько важных базовых классов WPF.
Роль класса Window
Класс System.Windows.Window (из сборки PresentationFramework.dll) представляет одиночное окно, которым владеет производный от Application класс, включая все отображаемые главным окном диалоговые окна. Тип Window вполне ожидаемо имеет несколько родительских классов, каждый из которых привносит дополнительную функциональность.
На рис. 24.1 показана цепочка наследования (и реализуемые интерфейсы) для класса System.Windows.Window, как она выглядит в браузере объектов Visual Studio.