tmori3y2のブログ

主にWindowsのプログラムなど

初心者が迷ったReactivePropertyを使用したModelのDirtyフラグ

大した説明もなく、さらっとIsDirtyをコードに紛れ込ませていましたが、元ネタはかずき大先生のこちらの記事。

blog.okazuki.jp

ReadOnlyReactivePropertyじゃなくして、クリアをIsDirty.Value = falseで出来るように端折っています・・・

tmori3y2.hatenablog.com

「なお、ModelのReactivePropertyModeをRaiseLatestValueOnSubscribeのみにしたら2行目は要らないが、POCOでは採用できないこと、通知サイクルが長くなること、IsDirtyが立つことから採用しなかった。」

と書いたが、View ModelのDirtyフラグを実装すると、"1.0"と表示されているところに"1"を入力するだけで、Dirtyになり都合が悪い・・・

そのため、次のようにmodelのプロパティを監視する。

今回は、UserControlとして実装しているので、HasErrors/IsDirty/CanUpdateBindingフラグの使い方をざっくり説明しておくと・・・

  • コントロール初期化(表示)
  • CanUpdateBindingフラグをクリアしてView ModelとViewの間のイベントをブロック
  • modelにメタデータを設定
  • modelにデータを設定
  • ここで一旦IsDirtyフラグが立つのでIsDirtyフラグをクリア
  • CanUpdateBindingフラグをセットしてViewにデータをロード

WindowをCloseする時はWindow_Closingのイベントハンドラで処理をする・・・

  • UserControlのViewのメソッドを呼び出し、編集中のデータをView Modelに読み込ませる
    • VisualTreeHelperで再帰的にデータバインドされたすべてのDependencyObjectからBindingExpressionを取得してUpdateSource()を呼び出す
  • HasErrorsフラグがセットされてたらキャンセル
  • CanUpdateBindingフラグをクリアしてView ModelとViewの間のイベントをブロック
  • IsDirtyフラグがセットされていたらデータソースにデータを保存

Dirtyフラグについては、以下が詳しい。

www.infoq.com