События времени существования

96

Все элементы генерируют события при создании и освобождении. Эти события можно использовать для инициализации окна. События времени существования перечислены ниже; все они определены в классе FrameworkElement.

Initialized

Возникает после создания экземпляра элемента и установки его свойств в соответствии с разметкой XAML. В этот момент элемент уже инициализирован, но другие части окна могут еще быть не инициализированными. Кроме того, еще не применены стили и привязка данных. Свойство IsInitialized имеет значение true. Данное событие является обычным событием .NET, а не маршрутизируемым.

Loaded

Возникает после завершения инициализации всего окна и применения стилей и привязки данных. Это последний этап перед прорисовкой элемента. В этот момент свойство isLoaded имеет значение true.

Unloaded

Возникает после освобождения элемента: или из-за закрытия содержащего его окна, или из-за удаления из окна данного элемента

Чтобы понять, как связаны между собой события Initialized и Loaded, полезно рассмотреть процесс прорисовки. FrameworkElement реализует интерфейс ISupportInitialize, который предоставляет два метода управления процессом инициализации. Первый из них, BeginInit(), вызывается сразу после создания экземпляра элемента. После этого вызова интерпретатор XAML устанавливает все свойства элемента (и добавляет любое содержимое). Второй метод, EndInit(), вызывается после завершения инициализации, когда возникает событие Initialized.

Это несколько упрощенное описание. Интерпретатор XAML самостоятельно вызывает методы BeginInit() и EndInit(), как и должно быть. Однако если создать элемент вручную и добавить его в окно, то вы вряд ли будете использовать этот интерфейс. В этом случае элемент сгенерирует событие Initialized сразу после добавления его в окно, непосредственно перед событием Loaded.

При создании окна каждая ветвь элементов инициализируется снизу вверх. Это означает, что глубоко вложенные элементы инициализируются до того, как будут инициализированы их контейнеры. Когда возникает событие Initialized, это означает, что дерево элементов от текущего элемента и ниже полностью инициализировано. Однако элемент, содержащий данный элемент, скорее всего, не инициализирован, и нет оснований предполагать, что инициализирована любая другая часть окна.

После инициализации каждого элемента он размещается в контейнере, обрабатывается стилями и при необходимости привязывается к источнику данных. После возбуждения события Initialized для окна пора переходить к следующему этапу.

После завершения процесса инициализации возникает событие Loaded. Оно распространяется в порядке, обратном событию Initialized: сначала событие Loaded генерируется во вмещающем окне, а затем его генерируют остальные вложенные элементы. Когда событие Loaded будет сгенерировано во всех элементах, окно станет видимым, и в нем будут прорисованы все элементы.

События времени существования, перечисленные выше — это еще не все. Содержащее окно имеет собственные события времени существования. Они перечислены ниже:

SourceInitialized

Возникает при получении свойства HwndSource (но перед тем, как окно станет видимым). HwndSource — это дескриптор окна, который может понадобиться для вызова устаревших функций интерфейса Win32 API.

ContentRendered

Возникает сразу после первой прорисовки окна. Здесь лучше не выполнять какие-либо изменения, которые могут повлиять на внешний вид окна, иначе придется выполнять еще одну прорисовку. (Используйте вместо него событие Loaded.) Однако событие ContentRendered означает, что окно является полностью видимым и готово для ввода.

Activated

Возникает, когда пользователь переключается на это окно (например, из другого окна в данном приложении или вообще из другого приложения). Это событие возникает также во время первой загрузки окна. В концептуальном плане событие Activated является "оконным" эквивалентом события GotFocus для элементов управления.

Deactivated

Возникает, когда пользователь выходит (т.е. переключается) из этого окна (например, переходит в другое окно в данном приложении или вообще в другое приложение). Это событие возникает также, когда пользователь закрывает окно, после события Closing, но перед событием Closed. В концептуальном плане событие Deactivated является "оконным" эквивалентом события LostFocus элементов управления.

Closing

Возникает при закрытии окна — либо пользователем, либо программно с помощью метода Window.Close() или Application.Shutdown(). Событие Closing позволяет отменить операцию и оставить окно открытым: достаточно присвоить свойству CancelEventArgs.Cancel значение true. Однако код не получит событие Closing, если приложение завершает работу вследствие того, что пользователь выключает компьютер или выходит из системы — для этого нужно обрабатывать событие Application.SessionEnding.

Closed

Возникает после закрытия окна. Объекты элемента еще доступны, а событие Unloaded еще не возникло. В этот момент можно выполнить зачистку, записать параметры для постоянного хранения (например, в конфигурационный файл или в системный реестр Windows) и т.д.

Если вам нужно просто выполнить первичную инициализацию элементов управления, то наилучшим моментом для этого является событие Loaded. Как правило, все действия, связанные с инициализацией, можно выполнить в одном месте — обычно это обработчик события Window.Loaded.

Для выполнения инициализации можно применять также конструктор окна (просто добавьте необходимый код сразу после вызова InitializeComponent()). Однако лучше всего использовать событие Loaded. Это связано с тем, что если в конструкторе Window возникнет исключение, оно будет сгенерировано во время разбора страницы интерпретатором XAML. В результате исключение будет упаковано в бесполезный объект XamlParseException (с исходным исключением в свойстве InnerException).

Пройди тесты
Лучший чат для C# программистов