No more Death March

あるSEのチラシの裏 C# WPF

WPF Window起動時のイベント発生順位をメモ

余り複雑な制御を行っているコントロールを作るのは好ましくないが、どうしてもやらなければならない場合が結構あったりする。そんな時に毎回イベントの発生順位ってどうだっけ?と忘れてしまうことがあるのでメモしておく。後述の通りサンプル画面を作ってビヘイビアで各イベントが着火したタイミングで発生したイベントをデバッグプリントしてやる。

<Window x:Class="WpfEventTracking.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        xmlns:local="clr-namespace:WpfEventTracking"
        mc:Ignorable="d"
        local:WindowBehavior.IsAttached="True"
        Title="MainWindow" Height="450" Width="800"
        >
    <GroupBox Header="GroupBox" local:ControlBehavior.IsAttached="True">
        <StackPanel>
            <TextBox Text="TextBox" local:ControlBehavior.IsAttached="True"/>
            <Button Content="Button" local:ControlBehavior.IsAttached="True"/>
        </StackPanel>
    </GroupBox>
</Window>

全てのイベントを網羅すると大変なので今回はUIElement、FrameworkElement、Control、Windowのイベントのみ出力する。

Window起動時

TextBox Initialized
Button Initialized
GroupBox Initialized
MainWindow Initialized
MainWindow IsVisibleChanged
GroupBox IsVisibleChanged
TextBox IsVisibleChanged
Button IsVisibleChanged
MainWindow SizeChanged
GroupBox SizeChanged
Button SizeChanged
TextBox SizeChanged
Button LayoutUpdated
TextBox LayoutUpdated
GroupBox LayoutUpdated
MainWindow LayoutUpdated
MainWindow Activated
MainWindow PreviewGotKeyboardFocus
MainWindow IsKeyboardFocusWithinChanged
MainWindow IsKeyboardFocusedChanged
MainWindow GotKeyboardFocus
Button LayoutUpdated
TextBox LayoutUpdated
GroupBox LayoutUpdated
MainWindow LayoutUpdated
MainWindow Loaded
GroupBox Loaded
TextBox Loaded
Button Loaded
MainWindow ContentRendered
Button LayoutUpdated
TextBox LayoutUpdated
GroupBox LayoutUpdated
MainWindow LayoutUpdated
Button LayoutUpdated
TextBox LayoutUpdated
GroupBox LayoutUpdated
MainWindow LayoutUpdated
Button LayoutUpdated
TextBox LayoutUpdated
GroupBox LayoutUpdated
MainWindow LayoutUpdated
Button LayoutUpdated
TextBox LayoutUpdated
GroupBox LayoutUpdated
MainWindow LayoutUpdated
Button LayoutUpdated
TextBox LayoutUpdated
GroupBox LayoutUpdated
MainWindow LayoutUpdated
Button LayoutUpdated
TextBox LayoutUpdated
GroupBox LayoutUpdated
MainWindow LayoutUpdated

LayoutUpdatedイベントまで出すと見難い・・・

Window起動時(LayoutUpdate無しver)

TextBox Initialized
Button Initialized
GroupBox Initialized
MainWindow Initialized
MainWindow IsVisibleChanged
GroupBox IsVisibleChanged
TextBox IsVisibleChanged
Button IsVisibleChanged
MainWindow SizeChanged
GroupBox SizeChanged
Button SizeChanged
TextBox SizeChanged
MainWindow Activated
MainWindow PreviewGotKeyboardFocus
MainWindow IsKeyboardFocusWithinChanged
MainWindow IsKeyboardFocusedChanged
MainWindow GotKeyboardFocus
MainWindow Loaded
GroupBox Loaded
TextBox Loaded
Button Loaded
MainWindow ContentRendered

LayoutUpdatedイベントを非表示にした再度確認

Window終了時

MainWindow Closing
MainWindow IsVisibleChanged
GroupBox IsVisibleChanged
TextBox IsVisibleChanged
Button IsVisibleChanged
MainWindow Deactivated
MainWindow IsKeyboardFocusWithinChanged
MainWindow IsKeyboardFocusedChanged
MainWindow LostKeyboardFocus
MainWindow Closed

ついでなのでWindow終了時の結果もメモ

まとめ

フォーカス取得系を省いて順番を整理すると
Initialize→IsVisibleChanged→SizeChanged→Activated→Loaded→ContentRendered→(画面表示完了)→Closing→IsVisibleChanged→Deactivec→Closed

バブルイベントとトンネルイベントを分けると

バブルイベント
Initialized

トンネルイベント
IsVisibleChanged
SizeChanged
Loaded

といった具合になる。

少し検索してみるとここで確認した通り、Windowのイベント発生順位がまとめられてた。

stackoverflow.com