はじめに
C++/CLIでWindowsアプリを作成した際に、フォームが表示された時とフォームが非表示になった時に処理したい状況がありました。iOSアプリやAndroidアプリでは、そのようなタイミングで呼び出されるライフサイクルメソッドが用意されているのを知っていましたので、Windowsアプリでも同様のライフサイクルメソッドがないか調べてみました。
iOSアプリのライフサイクルメソッド
参考ですがiOSアプリやAndroidアプリでは、フォームに該当するビュークラスの状態に応じて呼び出されるライフサイクルメソッドが、それぞれのタイミングで用意されています。以下はiOSアプリに用意されているライフサイクルメソッドで、それぞれのタイミングで呼び出されます。
(Androidアプリのライフサイクルメソッドは省略します)
メソッド名 | 説明 |
---|---|
loadView | カスタムビューの初期化を行うタイミング |
viewDidLoad | ビューがロードされた後のタイミング |
viewWillApper | ビューが表示される直前のタイミング |
viewWillLayoutSubviews | ビューがレイアウトされる直前のタイミング |
viewDidLayoutSubviews | ビューのレイアウトが完了したタイミング |
viewDidApear | ビューが表示された後のタイミング |
viewWillDisapper | ビューが表示されなくなる直前のタイミング |
viewDidDisapear | ビューが表示されなくなった後のタイミング |
Windowsアプリのイベント
同じようにWindowsアプリのフォームクラスにもライフサイクルメソッドがないか調べてみました。 次のサイトにライフサイクルメソッドではありませんが、フォームのそれぞれのタイミングではイベントが発生することがわかりました。
フォームが開始されるタイミングで発生するイベント
イベント名 | 説明 |
---|---|
Control.HandleCreated | コントロール(おそらくフォームのこと)が生成されたタイミング |
Control.BindingContextChanged | BindingContextプロパティが変更されたタイミング |
Form.Load | フォームが最初にロードされたタイミング |
Control.VisibleChanged | Visibleプロパティが変更されたタイミング |
Form.Activated | ユーザによってフォームがアクティブ化されたタイミング |
Form.Shown | フォームが最初に表示されたタイミング |
フォームが終了されるタイミングで発生するイベント
イベント名 | 説明 |
---|---|
Form.Closing | フォームがクローズされ始めたタイミング |
Form.FormClosing | フォームがクローズされる前のタイミング |
Form.Closed | フォームがクローズされた後のタイミング |
Form.Deactivate | フォームが破棄されるタイミング |
イベントの絞り込み
各イベントの発生するタイミングを調べてみて、今回の要求を満たしそうなControl.VisibleChanged/Form.Activated/Form.Shownイベントに着目しました。
まずForm.Shownイベントですが、説明にもあるようにフォームが最初に表示されたタイミングで発生します。そのため"表示されるタイミング"という要求に合致するように思いましたが、フォームが一旦非表示になって再表示された時にForm.Shownイベントは発生しないため使えないことがわかりました。
次にForm.Activatedイベントですが同じくフォームが表示されるタイミングで発生します。そのため通常であれば"表示されるタイミング"という要求を満たします。
しかし今回のアプリの作りが特殊で、複数のフォームを表示しておきボタン押下により表示するフォームを切り替えるといった仕組みにしたため予期せぬタイミングでForm.Activatedイベントが発生してしまい使えませんでした。
Control.VisibleChangedイベント
最後に残ったControl.VisibleChantedイベントですが、説明をみると発するタイミングは"Visibleプロパティが変更されたタイミング"とあります。
次にVisibleプロパティを調べてみると、コントロール(フォーム)が表示されたかどうかの値(Bool値)が設定されるとあります。そのためこのControl.VisibleChangedイベントのイベントハンドラで、Visibleプロパティの状態を判定して、フォームが表示されたタイミング/非表示になったタイミングを判断することにしました。
サンプル
以下のようにフォームのVisibleChangedイベントハンドラを追加して処理を記述しました。
private: System::Void SampleForm_VisibleChanged(System::Object^ sender, System::EventArgs^ e) { if (this->Visible) { // フォームが表示された時の処理 } else { // フォームが非表示になった時の処理 } }
おわりに
今回iOSアプリのライフサイクルメソッドのタイミングとWindowsアプリのイベントのタイミングを整理してみると、似ているようで違うと感じました。感覚的な問題かもしれませんが、Windowsアプリのイベントのタイミングは自分にとっていまいち使いづらいと感じました。 今回調べきれなかったイベントについても機会があれば調べてみたいと思います。