В предыдущих главах мы работали непосредственно с окном приложения, которое представлено классом Window, его разметкой, добавляли в нее элементы, создавали для него код на C#. Однако само приложение начинается не с класса Window, а с класса Application. По умолчанию при создании проекта WPF создается файл App.xaml и класс связанного кода App.xaml.cs:
Файл App.xaml выглядит примерно так:
<Application x:Class="HelloApp.App" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:local="clr-namespace:HelloApp" StartupUri="MainWindow.xaml"> <Application.Resources> </Application.Resources> </Application>
С помощью атрибута x:Class
элемент Application задает полное название производного класса приложения. По умолчанию класс называется App, с указанием названия проекта, то есть
в данном случае HelloApp.App
Как правило, основная задача данного файла состоит в определении ресурсов, общих для приложения. Поэтому тут по умолчанию определен пустой элемент Application.Resources
,
в который, собственно, и помещаются ресурсы.
Также здесь декларативным путем можно прикрепить к событиям приложения обработчики.
С помощью атрибута StartupUri устанавливается путь к разметке xaml, с которого начинается выполнение приложения. По умолчанию это разметка окна MainWindow, определенного в файле MainWindow.xaml. Если у нас в приложении несколько окон, тут мы можем указать то, которое будет запускаться при вызове приложения.
файл App.xaml.cs также содержит определение класса App. По умолчанию этот класс совершенно пустой:
public partial class App : Application { }
В нем мы можем задать обработчики событий приложения, либо какую-то другую глобальную для всего приложения логику.
Таким образом, у нас получается, что оба файла App.xaml и App.xaml.cs содержат определение одного и того же класса App.
Однако в конечном счете они будут компилироваться в один файл приложения App.g.cs, который вы можете
найти после компиляции приложения в каталоге проекта obj/Debug/netX.0-windows
Данный класс будет выглядеть примерно так:
public partial class App : System.Windows.Application { [System.Diagnostics.DebuggerNonUserCodeAttribute()] [System.CodeDom.Compiler.GeneratedCodeAttribute("PresentationBuildTasks", "7.0.3.0")] public void InitializeComponent() { #line 5 "..\..\..\App.xaml" this.StartupUri = new System.Uri("MainWindow.xaml", System.UriKind.Relative); #line default #line hidden } [System.STAThreadAttribute()] [System.Diagnostics.DebuggerNonUserCodeAttribute()] [System.CodeDom.Compiler.GeneratedCodeAttribute("PresentationBuildTasks", "7.0.3.0")] public static void Main() { HelloApp.App app = new HelloApp.App(); app.InitializeComponent(); app.Run(); } }
Входной точкой в программу (как и в любое другое приложение на C#) является метод Main, в котором создается экземпляр приложения и производится начальная инициализация и вызов главного окна программы.
Так как WPF требует, чтобы главный поток работал в однопоточном подразделении (Single-threaded apartment), то метод Main помечается атрибутом
STAThreadAttribute
. Однопоточное подразделение содержит один поток, в данном случае главный. Это означает, что к элементам, созданным
в этом потоке можно обратиться только из этого же потока. В то же время WPF предлагает эффективный способ взаимодействия между потоками, о котором мы позже поговорим.
С помощью метода InitializeComponent происходит инициализация приложение: установка главного окна для запуска. И далее само приложение запускается
через вызов app.Run()
.
Также в той же папке можно найти файл App.g.i.cs, который имеет идентичное содержимое, но применяется различными службами Visual Studion, например, Intellisense.
Однако это не жестко заданная организация файлов приложения, и мы ее можем переопределить и установить точку входа в приложение сами. Для этого, во-первых, удалим файл App.g.cs. И во-вторых, изменим код App.xaml.cs:
using System; using System.Windows; using HelloApp; public partial class App : Application { [STAThread] static void Main() { App app = new App(); MainWindow window = new MainWindow(); window.Title = "Hello METANIT.COM"; app.Run(window); } }
Фактически файл App.xaml.cs стал похож на компилируемый файл App.g.cs. Здесь мы сразу определяем метод Main, создаем главное окно - объект класса MainWindows, устанавливаем его заголовок и запускаем ее.
И после запуска нам отобразится главное окно приложения с измененным заголовком.