問題

2011-07-08 27 views
0

私は3ステップは、私は2つの部分に分かれてMAINVIEW持っている機能問題

を保存実装する必要がありそのための要件が​​あります。

  • 左部分をその内部にTreeViewを有するUserControlを有する。
  • 右部分は、TreeViewUserControlで選択された項目に応じてUserControlをホストするContentControlを持ちます。

私はあなたに例を挙げます。

リーフノードをクリックすると、データUserControlが入力され、モデル - > ViewModel-> View(UserControl)のそれぞれの選択されたTreeView Itemのデータが設定されます。ユーザーがデータを変更して保存する場合は、を一時的にに保存し、すべての変更をキャンセルした場合は破棄する必要があります。 TreeViewに新しいノードを追加するとき、同じ振る舞いを実証する必要があります。

[ファイル]メニューの[保存]をクリックしたときにのみ、データがシリアル化されてディスクに保存されます。

さらに、ユーザーがナビゲートしようとすると、変更を保存またはキャンセルするまでユーザーが移動しないようにしたいと考えています。

このようなシナリオでは、これらのデータオブジェクトの一時的な状態を保存する際に問題があります。私は浅いコピーを使用しようとしましたが、これは主なEntity(ファイルが読み込まれる時に初期化される)の参照のみを与えるので動作しません。

他の方法はありますか?

+0

あなたのデータはどこから来ていますか、どのような形式ですか? –

+0

テキストの読み上げをしないでください。あなたがそれを十分に行えば、システムはあなたに質問を自動的にブロックします。 – Will

答えて

0

あなたの質問はWPFまたはMVVMとはあまり関係ありません。モデルの状態の変更を追跡し、ViewModelsからすべてのモデルの状態を照会して、ユーザーが離れることを許可するかどうかを判断できるようにする必要があります。

残念ながら、フレームワークはネイティブにこのパターンをサポートしていません。あなたはそれを自分で書かなければなりません。

各モデルがインタフェースを実装し、IDirtyを言うことができます:私は(約)これを実現する方法を

。このインターフェイスには、次のプロパティ/メソッドがあります。

  • IsDirty {get; }
  • CancelEdit();
  • AcceptEdit();

作成時に、モデルは汚れていません(IsDirty == false)。プロパティが変更されると、Dirtyになります。すべてのプロパティの元の状態も記憶されます。ユーザーがキャンセルすると、CancelEdit()が呼び出され、元の状態に戻ります。 AcceptEdit()が呼び出された場合、元の状態は現在の状態で上書きされます。

また、カスタムのObservableCollectionの実装を作成して、内に含まれるすべてのモデルの状態をクエリして、汚れていないかどうかを判断することもできます。私のViewModelsと同じです。そのため、ViewはViewModelのIsDirtyプロパティにバインドできます。これは、ViewModel内のすべてのモデルコレクションを照会します。同様に、CancelEditAcceptEditへのコールもチェーンされているため、ViewModelでAcceptEdit()を呼び出すと、その中のすべてのモデルにAcceptEditが呼び出されます。

これは、非常にになります。このタイプの機能を提供するように設計されたフレームワークがいくつかあります。私はちょっとしたことを知らない。

0

標準のWPFバインディング手法を使用する場合は、ロバストなフォーム処理を実現することは非常に困難です。

これは、IsDirty、ViewModel.IsDirty(あなたの責任)とBinding.IsDirty(WPFの責任)の2種類があるからです。

Binding.IsDirtyは、TextBox Text値が変更されたときに発生しますが、バインディングソースに送信されていません。

ViewModel.IsDirtyがfalseで、Binding.IsDirtyがtrueである可能性があります。

これは、TextBoxのデフォルトのUpdateSourceTriggerがPropertyChangedではなくLostFocusであるために発生します。

それは残念ながらWPFバインディングクラスにはない

(検証が部分編集時に失敗し、ユーザー入力の一定の再フォーマットがあるでしょう)そうでない場合のDateTime(など)を編集すると、ユーザーを戦うことになる。このようにする必要がありIsDirty機能を実装するには、それが完璧な位置にあるとはいえ、Source(ViewModel)とTarget(TextBox)の両方にアクセスでき、すべての関連イベントが通知されます。

さらに、Bindingクラスの設計は、この機能で拡張されることはできません。 IMOそれは「ブラックボックス」であり、ソフトウェアを設計しない方法の素晴らしい例です。

私の解決策は、自分のBindingクラスを作成してから、再び生産性を高めることです。