モードレス ウィンドウで画面遷移を行う WPF アプリケーションを作ったので、構造を整理してライブラリ化してみました。
プログラムの前に、画面遷移の制御について概要を説明します。
制御の概要をアクティビティ図にまとめてみました(スペースの関係と全体概要の把握が目的なので簡略な書き方をしています 😉 )。
A -> B -> C -> A と画面遷移を行う場合、B を表示する際に A を非表示にし、同様に C を表示する際に B を非表示にします。C で必要な手順が完了して閉じる際には、C, B をクローズして A を表示します。C で必要な手順を完了せずに閉じる場合には、C をクローズして B を再表示します。
こういった制御をライブラリ側で行うようにしたものです。実際の構造としては、ウィンドウの制御はビヘイビア(アクション)で行い、ビューモデルのプロパティ変更でアクションが起動するように、ビューで Blend SDK の PropertyChangedTrigger を使用してビューモデルのプロパティに結びつける方式としています(ビューでの PropertyChangedTrigger の記述は各アプリケーション側で行う必要があります)。
アプリケーション例を含めた TransitionViewModelBase の ZIP ファイルを ViewModelBase のページからダウンロードできるようにしたので、ファイルがほしい方はそちらから入手してください。
次に、仕様です。
TransitionViewModelBase
データ検証と画面遷移及び表示状態設定機能を持つビューモデルの基底クラス
構文
public abstract class TransitionViewModelBase : DialogViewModelBase, IWindowCloseCommand, IViewModelStatus, IReceiveFinished
プロパティ
-
public WindowAction DisplayMode { get; protected set; }
- ウィンドウの表示状態を取得・設定します。
View 側で PropertyChangedTrigger の Binding と DisplayModeAction の DisplayMode にバインドしてください。 -
protected TransitionViewModelBase PreviousViewModel { get; }
- 前画面のビューモデルを取得します。
-
public override object Container {get; set; }
- ウィンドウ作成元からのデータ受け取り用プロパティ
-
public bool CanCloseWindow { get; }
- ウィンドウを閉じることが可能かを取得します。
-
public ViewModelStatus CurrentStatus { get; set; }
- ビューモデルの処理状態を取得・設定します。
メソッド
-
protected virtual bool WindowCloseCanExecute(object param)
- ウィンドウが閉じることの出来る状態かどうかを返します。
仮想メソッドは常に ‘true’ を返します。制御が必要な場合はオーバーライドしてください。 -
protected virtual void OnWindowClosed()
- ウィンドウがクローズされた際の操作
-
protected virtual void TransitionComplete()
- 一連の画面遷移の完了を設定します。
-
public virtual void WindowClose()
- ビューモデルからウィンドウへ Close を通知するメソッドです。
-
public virtual void OnFinished(ITransContainer container)
- 画面遷移完了時に実行する処理です。
コマンド
-
public ICommand WindowCloseCommand { get; }
- ウィンドウを閉じるコマンド
-
public ICommand WindowClosedCommand { get; }
- ウィンドウがクローズされた際の操作コマンド
ウィンドウの Closed イベントが発生した際に呼び出されるようにしてください。
DialogViewModelBase
データ検証とダイアログ表示の基本機能を提供するビューモデルの基底クラス
構文
public abstract class DialogViewModelBase : ValidationViewModelBase, IDialogTransferContainer
プロパティ
-
public object CommunicationDialog { get; protected set; }
- 作成する Dialog に渡すデータを取得・設定します。
View 側で DialogTransferDataAction の Parameter にバインドしてください。 -
public Type DialogType { get; protected set; }
- 表示するカスタムダイアログボックスの型の情報
View 側で DialogTransferDataAction の DialogType にバインドしてください。 -
public virtual object Container { get; set; }
- ウィンドウ作成元から渡されたデータの受取用
-
public Action<bool?> DialogActionCallback { get; protected set; }
- ダイアログが閉じられた後に実行するコールバックを取得・設定します。
View 側で DialogTransferDataAction の ActionCallBack にバインドしてください。 -
public object ResultViewModel { get; set; }
- ダイアログ表示で生成されたダイアログのビューモデルへの参照を取得・設定します。
(ダイアログで設定された値の参照用)
View 側で DialogTransferDataAction の ResultViewModel にバインドしてください。 -
public MessageDialogActionParameter MessageDialogActionParam { get; set; }
- MessageDialogActionに渡すパラメーター
View 側で PropertyChangedTrigger の Binding と MessageDialogAction の Parameter にバインドしてください。 -
public Action<MessageBoxResult> MessageDialogActionCallback { get; set; }
- MessageDialogActionの実行後に呼ばれるCallBack
View 側で MessageDialogAction の ActionCallBack にバインドしてください。
メソッド
-
protected virtual void OnContainerReceived(object container)
- ウィンドウ作成元からのデータを受け取った際に行う処理
ModalViewModelBase
データ検証とモーダルダイアログ表示機能を持つビューモデルの基底クラス
構文
public abstract class ModalViewModelBase : DialogViewModelBase
プロパティ
-
public bool? Result { get; set; }
- View 側の DialogResult セット用の PropertyChangedTrigger へバインドします。
View 側で PropertyChangedTrigger の Binding と ChangePropertyAction の Value にバインドしてください。
メソッド
-
protected virtual void OkExecute()
- モーダルダイアログの OK ボタンクリック時の処理
仮想メソッドは Window の DialogResult プロパティに true をセットする動作のみです。制御が必要な場合はオーバーライドしてください。 -
protected virtual bool OkCanExecute(object param)
- OkCommand の 有効/無効 を返します。
データ検証エラーの有無を返します。データ検証エラーを用いないで判断したい場合はオーバーライドしてください。
コマンド
-
public ICommand OkCommand { get; }
- OK ボタン用のコマンドです。
ボタンの有効・無効をコントロールするため、コマンドで Window の DialogResult を設定します。
TransitionContainerBase
画面遷移の際のデータコンテナの基底クラス
構文
public class TransitionContainerBase : ITransContainer
コンストラクタ
-
public TransitionContainerBase(string key, TransitionViewModelBase viewModel)
- 画面遷移のキー及び遷移開始元ビューモデルを設定して画面遷移の際のデータコンテナを作成します。
プロパティ
-
public string Key { get; }
- 遷移を区別するためのキーを取得します。
-
public TransitionViewModelBase TransStartViewModel { get; }
- 遷移動作の開始元ビューモデルを取得します。
-
public TransitionViewModelBase PreviousViewModel { get; set; }
- 前画面のビューモデルを取得・設定します。
ITransContainer
画面遷移の際のデータコンテナのインターフェイス
構文
public interface ITransContainer
プロパティ
-
string Key { get; }
- 遷移を区別するためのキーを取得します。
-
TransitionViewModelBase TransStartViewModel { get; }
- 遷移動作の開始元ビューモデルを取得します。
-
TransitionViewModelBase PreviousViewModel { get; set; }
- 前画面のビューモデルを取得・設定します。
ViewModelUtility
ViewModel 関連のユーティリティクラス
構文
public static class ViewModelUtility
メソッド
-
public static ViewModelBase GetMainWindowViewModel()
- MainWindow となっている Window の ViewModel を返します。
-
public static int Count(Type type)
- 指定されたビューモデルのインスタンスの数を返します。
-
public static IReadOnlyList<ViewModelBase> GetViewModels(Type type)
- 指定されたビューモデルのインスタンスの一覧を返します。
-
public static void CloseViewModels(Type type)
- 指定されたビューモデルのインスタンスの IWindowCloseCommand インターフェイス のWindowClose メソッドを実行します。
-
public static bool IsReadyCloseAllWindows
- すべてのウィンドウが閉じることが可能か確認します。
DialogTransferDataAction
データを渡してモードレス ダイアログ ウィンドウを表示するアクション
ダイアログ側のビューモデルにデータ受取り用の「public object Container」プロパティが必要
構文
public class DialogTransferDataAction : TriggerAction<FrameworkElement>
プロパティ
-
public object Parameter { get; set; }
- ダイアログウィンドウに渡すデータを格納
-
public Type DialogType { get; set; }
- 表示するダイアログのクラス名
-
public DialogModes DialogMode { get; set; }
- ダイアログの表示種別
-
public Action<bool?> ActionCallBack { get; set; }
- ダイアログを閉じた際に実行するコールバック
-
public object ResultViewModel { get; set; }
- 作成したウィンドウのビューモデルオブジェクトへの参照
ダイアログ側で設定したデータの参照用
DialogModes
ダイアログの表示種別
構文
public enum DialogModes
メンバー
- Modal
- モーダル ダイアログとして表示する。
- Modeless
- モードレス ダイアログとして表示する。
DisplayModeAction
モードレス ウィンドウの表示変更アクション
構文
public class DisplayModeAction : TriggerAction<FrameworkElement>
プロパティ
-
public WindowAction DisplayMode { get; set; }
- 変更する表示状態
WindowAction
画面遷移を行うビューモデルへセットするウィンドウの状態
構文
public enum WindowAction
メンバー
- Show
- 表示する
- Hide
- 非表示にする
- Close
- 閉じる
MessageDialogAction
MessageBox を表示するアクション
構文
public class MessageDialogAction : TriggerAction<FrameworkElement>
プロパティ
-
public IMessageDialogActionParameter Parameter { get; set; }
- メッセージボックスやダイアログを出すために必要となる情報を受け取る
-
public Action<MessageBoxResult> ActionCallBack
- ダイアログでの選択結果をViewModelに通知するコールバックメソッド
IDialogTransferContainer
生成元ウィンドウからのデータの受取用プロパティのインターフェイス
構文
public interface IDialogTransferContainer
プロパティ
-
object Container { get; set; }
- 生成元ウィンドウからのデータの受取用プロパティ
IMessageDialogActionParameter
MessageDialogAction へ渡すパラメーターのインターフェイス
IsDialog が false のときには Button の設定は反映されません。
構文
public interface IMessageDialogActionParameter
プロパティ
-
string Message { get; }
- MessageBoxに表示するメッセージ
-
string Caption { get; }
- MessageBox に表示するタイトル
-
MessageBoxButton Button { get; }
- MessageBox に表示するボタン
-
bool IsDialog { get; }
- true:ダイアログ(ユーザ応答を処理する)、false:メッセージ
ValidationViewModelBase
プロパティ変更通知及びデータ検証を実装したビューモデルの基底クラス
構文
public abstract class ValidationViewModelBase : WeakEventViewModelBase, IDataErrorInfo
プロパティ
-
public bool IsValid
- データ検証エラーの発生の有無を取得します。
-
public ValidationDictionary ViewModelState
- ビューモデルの状態及びバインディングの検証の状態を格納するビューモデル状態ディクショナリ オブジェクトを取得します。
メソッド
-
public void RemoveItemValidationError<T>(Expression<Func<T>> propertyName)
- propertyName に設定されている検証エラーメッセージを削除します。
-
public void RemoveItemValidationError(string propertyName)
- propertyName に設定されている検証エラーメッセージを削除します。
-
public bool IsPropertyAnnotationError<T>(Expression<Func<T>> propertyName)
- 指定されたプロパティの System.ComponentModel.DataAnnotations のデータ検証アトリビュート検査の結果を確認します。
-
public bool IsPropertyAnnotationError(string propertyName)
- 指定されたプロパティの System.ComponentModel.DataAnnotations のデータ検証アトリビュート検査の結果を確認します。
-
protected void RaisePropertyChangedWithRemoveItemValidationError<T>(Expression<Func<T>> e)
- PropertyChanged イベントを発火します。
プロパティ変更通知まえに当該プロパティの検証エラーの削除を行います。 -
protected virtual void RaisePropertyChangedWithRemoveItemValidationError(string propertyName)
- PropertyChanged イベントを発火します。
プロパティ変更通知まえに当該プロパティの検証エラーの削除を行います。
ValidateConditionalAttribute
データ検証を行う条件を指定します。
構文
[AttributeUsage(AttributeTargets.Property)]
public class ValidateConditionalAttribute : Attribute
コンストラクタ
-
public ValidateConditionalAttribute(string comparedProperty, object value)
プロパティ
-
public string ComparedProperty
- 条件の比較対象となるプロパティ名を取得します。
-
public object Value
- 条件となる値を取得します。
WeakEventViewModelBase
弱いイベントパターンを用いたリスナー登録機能を持つビューモデルベースです。
構文
public abstract class WeakEventViewModelBase : ViewModelBase
メソッド
-
public void AddListener(INotifyPropertyChanged notifyObject, IWeakEventListener weakEventListener)
- PropertyChangedEventManager へ弱いイベントのリスナーを登録します。
ViewModelBase
プロパティ変更通知を実装したビューモデルの基底クラス
構文
public abstract class ViewModelBase : NotifyObject, IDisposable
メソッド
-
public void Dispose()
- リソースの開放を行います。
-
protected virtual void Dispose(bool disposing)
- リソースの開放を行います。
NotifyObject
プロパティ変更通知を実装した基底クラス
構文
public abstract class NotifyObject : INotifyPropertyChanged
プロパティ
-
protected Dispatcher UiDispatcher { get; }
- UI スレッドのディスパッチャ
メソッド
-
protected void RaisePropertyChanged<T>(Expression<Func<T>> e)
- PropertyChanged イベントを発火します。
-
protected virtual void RaisePropertyChanged(string propertyName)
- PropertyChanged イベントを発火します。
イベント
-
public event PropertyChangedEventHandler PropertyChanged
- PropertyChanged イベント処理用のデリゲート
interface IValidationDictionary
データ検証のインターフェイス
構文
public interface IValidationDictionary
プロパティ
-
bool IsValid { get; }
- データ検証エラーの発生の有無を取得する。
メソッド
-
void AddError(string key, string errorMessage)
- データ検証エラーメッセージを追加する。
-
IEnumerator<KeyValuePair<string, ModelState>> GetEnumerator()
- コレクションを反復処理するために使用できる列挙子を返します。
PropertyHelper
構文
public interface IValidationDictionary
メソッド
-
public static string GetName<T>(Expression<Func<T>> e)
- 引数で渡されたプロパティから当該プロパティの名前を返します。
長くなったので、プログラムは次回に。。。
「ダイアログ表示を行うビューモデル(その1)」への1件のフィードバック