Язык программирования C#9 и платформа .NET5
Построение класса приложения
В любом приложении WPF нужно будет определить класс, расширяющий
. Внутри такого класса определяется точка входа программы (методApplication), которая создает экземпляр данного подкласса и обычно обрабатывает событияMain()иStartup(при необходимости). Вот пример:Exit<b>// Определить глобальный объект приложения для этой программы WPF.</b>class MyApp : Application{[STAThread]static void Main(string[] args){<b> // Создать объект приложения.</b>MyApp app = new MyApp();<b> // Зарегистрировать события Startup/Exit.</b>app.Startup += (s, e) => { /* Запуск приложения */ };app.Exit += (s, e) => { /* Завершение приложения */ };}}В обработчике события
чаще всего обрабатываются входные аргументы командной строки и запускается главное окно программы. Как и следовало ожидать, обработчик событияStartupпредставляет собой место, куда можно поместить любую необходимую логику завершения программы(например, сохранение пользовательских предпочтений).ExitНа заметку! Метод
приложения WPF должен быть снабжен атрибутомMain(), который гарантирует, что любые унаследованные объекты СОМ, используемые приложением, являются безопасными в отношении потоков. Если не аннотировать метод[STAThread]подобным образом, тогда во время выполнения возникнет исключение. Даже после появления в версии C# 9.0 операторов верхнего уровня вы все равно будете стремиться использовать в приложениях WPF традиционный методMain(). В действительности методMain()генерируется автоматически.Main()Перечисление элементов коллекции Windows
Еще одним интересным свойством класса
являетсяApplication, обеспечивающее доступ к коллекции, которая представляет все окна, загруженные в память для текущего приложения WPF. Вспомните, что создаваемые новые объектыWindowsавтоматически добавляются в коллекциюWindow. Ниже приведен пример метода, который сворачивает все окна приложения(возможно в ответ на нажатие определенного сочетания клавиш или выбор пункта меню конечным пользователем):Application.Windowsstatic 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 показана цепочка наследования (и реализуемые интерфейсы) для класса
, как она выглядит в браузере объектов Visual Studio.System.Windows.WindowПо мере чтения этой и последующих глав вы начнете понимать функциональность, предлагаемую многими базовыми классами WPF. Далее представлен краткий обзор функциональности каждого базового класса (полные сведения ищите в документации по .NET 5).
Роль класса System.Windows.Controls.ContentControl
Непосредственным родительским классом
является классWindow, который вполне можно считать самым впечатляющим из всех классов WPF. Базовый классContentControlснабжает производные типы способностью размещать в себе одиночный фрагмент содержимого, который, выражаясь упрощенно, относится к визуальным данным, помещенным внутрь области элемента управления через свойствоContentControl. Модель содержимого WPF позволяет довольно легко настраивать базовый вид и поведение элемента управленияContent.ContentControlНапример, когда речь идет о типичном "кнопочном" элементе управления, то обычно предполагается, что его содержимым будет простой строковый литерал (ОК, Cancel, Abort и т.д.). Если для описания элемента управления WPF применяется XAML, а значение, которое необходимо присвоить свойству
, может быть выражено в виде простой строки, тогда вот как установить свойствоContentвнутри открывающего определения элемента:Content<b><! -- Установка значения Content в открывающем элементе --></b><Button Height="80" Width="100" Content="OK"/>На заметку! Свойство
можно также устанавливать в коде С#, что позволяет изменять внутренности элемента управления во время выполнения.ContentОднако содержимое может быть практически любым. Например, пусть нужна "кнопка", которая содержит в себе что-то более интересное, нежели простую строку — возможно специальную графику или текстовый фрагмент. В других инфраструктурах для построения пользовательских интерфейсов, таких как Windows Forms, потребовалось бы создать специальный элемент управления, что могло повлечь за собой написание значительного объема кода и сопровождение полностью нового класса. Благодаря модели содержимого WPF необходимость в этом отпадает.

