ソフトウェア

C# WPFアプリ(Livet)の画面遷移を理解する

はじめに

C# WPFアプリケーション Livetの画面遷移の例をご紹介します。
WPFアプリケーション開発を行う上で必要不可欠なものです。
サンプルコードを用いて解説していきます。

フォームアプリケーション開発の場合とはかなり異なります。

画面遷移の例

別の画面を表示する

Livetを用いて画面を表示するときはViewへ表示メッセージを送信することで実現します。

別の画面を表示するのにメッセージを送信?初めてWPFアプリケーション開発を行う人は戸惑うかもしれません。
私もそうでした。
メッセージを送信して画面が表示される本質的な仕組みは別の記事
C# WPFアプリ XAMLのトリガー→アクションを理解する
で紹介しています。

Livetでの画面表示方法
ViewModelからViewへ表示メッセージを送信する。

Messenger.Raise(new TransitionMessage(【Viewクラス名】),new 【ViewModelクラス名】, 【モードレス or モーダル指定】,"Transition" ));

ここで、【モードレス or モーダル指定】には
TransitionMode.Normal(モードレス)
TransitionMode.Modal(モーダル)
他を指定します。

モーダル画面は表示している間、他の画面の操作ができません。
モードレス画面は表示している間でも他の画面の操作できます。

最後の"Transition"のところは他の文言例えば"Open"などでも可能ですが、その場合、View側で同じように変更する必要があります。
LivetのInteractionMessageTriggerクラスのMessageKeyの値を"Transition"から"Open"へ変更したりなどですね。

サンプルコードをのせておきます。

【ViewModel側】

    // 遷移先のViewModelのインスタンス生成
    var xxxVM = new xxxViewModel();
    // 遷移先のViewへ送るメッセージの作成
    var message = new TransitionMessage(
                 typeof(Views.xxxWindow), xxxVM, TransitionMode.Modal, "Transition");
    //遷移先のViewへメッセージ送信
    Messenger.Raise(message);

Viewへ画面遷移メッセージ"Transiotion"を送信します。

【View側】

<Window ...>
    ...
    <l:InteractionMessageTrigger MessageKey="Transition" Messenger="{Binding Messenger}">
        <l:TransitionInteractionMessageAction/>
    </l:InteractionMessageTrigger>
    ...
</Window>

メッセージ"Transiotion"を受信したら、画面を表示するアクションTransitionInteractionMessageActionが実行されます。

メインウィンドウをアクティブにする

複数画面を同時に開いていて、何かのイベント、例えばプッシュ通知やメールの着信などがあったとき、メイン画面をトップに再表示したい場合があります。
これをC# WPFアプリで実現するサンプルコードをご紹介します。

private void doMainWindowActive()
{
    DispatcherHelper.UIDispatcher.BeginInvoke( (Action)(() => {
        var windows = Application.Current.Windows.Cast();
        foreach( var w in windows ){
            /// ウインドウ・タイトルでメインウィンドウかを判定
            if( w.Title.Equals( "メイン画面" ) ){
                /// 最小化している場合はウィンドウサイズを元へ戻す
                if( w.WindowState == WindowState.Minimized ){
                    w.WindowState  = WindowState.Normal;
                }
                /// メインウィンドウをアクティブにする
                w.Activate();
                
                /// ウィンドウを最前面へ移動
                w.Topmost = true;
                w.Topmost = false;
                break;
            }
        }
    }));
}

w.Topmost = false;としているのはtrueのままでは、ずっと最前面になってしまうためです。
なお、上のサンプルはLivetの利用有無に関係なく、C#アプリケーションであれば、使うことができます。

メインウィンドウ以外、すべての画面を同時に閉じる

メインウィンドウ画面以外、すべての画面を同時に閉じたい場合があります。
たとえば、たくさんのモードレスな画面を表示していた場合など。
これをC# WPFアプリで実現するサンプルコードをご紹介します。
先ほどのメインウィンドウをアクティブにする方法と本質的には同じです。

private void doAllCloseWindow()
{
    var windows = Application.Current.Windows.Cast();
    foreach( var w in windows ){
        /// メインウィンドウは閉じない
        if( w.Title.Equals( "メイン画面" ) ){
            continue;
        }
        /// 子ウインドウを閉じる
        w.Close();
    }
}

上のサンプルはLivetの利用有無に関係なく、C#アプリケーションであれば、使うことができます。

自分のウィンドウを閉じる

画面を処理が終わったら、自分で閉じたい場合があります。
例えば、わかりやすいものとしてログイン画面があります。
ログインに成功したらログイン画面が閉じますよね。

これを実現するためにC# WPFアプリ的にいえば、ログイン画面のViewとバインドしているViewModelからログイン画面のViewに対して、画面クロースメッセージを送信するということです。
サンプルコードをご紹介します。

【ViewModel側】

Messenger.Raise(new WindowActionMessage(WindowAction.Close, "WindowAction"));

Viewへ"WindowAction"メッセージを送信します。

【View側】

<i:Interaction.Triggers>
    <l:InteractionMessageTrigger MessageKey="WindowAction" Messenger="{Binding Messenger}">
        <l:WindowInteractionMessageAction />
    </l:InteractionMessageTrigger>
</i:Interaction.Triggers>

View側でMessageKeyでも指定する"WindowAction"メッセージを受信したら、WindowActionに紐づいてオプション、この場合、Closeアクションを実行します。

簡易ダイアログを表示

簡易ダイアログ、例えば、エラー画面とか完了画面を表示したい場合があります。
これを実現するためのサンプルコードをご紹介します。

完了画面の例です。ボタンはOKボタンのみです。

///メッセージの作成
var message = new ConfirmationMessage(
                      "テストボタンが押されました。",
                      "テスト画面",
                      System.Windows.MessageBoxImage.Information,
                      System.Windows.MessageBoxButton.OK,
                      "Confirmation");
///メッセージの送信
Messenger.Raise(message);

System.Windows.MessageBoxImage.Informationを
System.Windows.MessageBoxImage.Errorにすると
アイコンが青いアイコンから赤いエラーアイコンに変わります。

また
System.Windows.MessageBoxButton.OK
System.Windows.MessageBoxButton.Yesにすると
OKボタンひとつから「はい」と「いいえ」のボタンが2つ表示されます。

最後に

C# WPFアプリケーション Livetの画面遷移の方法をサンプルコードを用いてご紹介してきました。
一部、メイン画面をアクティブにする、複数の画面を同時に閉じるで紹介したサンプルはLivetの利用に関係なくC#アプリケーションであれば、使うことができます。

Livetに関していえば、画面遷移はViewへViewModelからメッセージを送信することで実現することがポイントです。
細かいコードは正直、覚えなくても問題ありません。
Visual C#の入力補完機能やインターネット上に.NetフレームワークやLivetの公式ドキュメント、他様々な情報があるので、基礎となる概念さえ抑えておけば、大丈夫です。

-ソフトウェア