• Встроенный механизм стилей, который позволяет определять "темы" для приложения 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