4

WPFデータ入力画面の取り消しジャーナルを作成しています。このジャーナルは、すべてのコントロールにわたる変更を追跡します。ユーザーが[元に戻す]を選択したときに、最新の変更を元に戻すだけでなく、値が元に戻されるコントロールにフォーカスを戻したいと思います。私はその焦点を元に戻すための最良の方法に苦労しています。

私のViewModelは、元にされるジャーナリングを処理する部分になります。ViewModelのプロパティセッターは、DataModelを更新する前に「前」の状態をキャプチャします。どういうわけか、その「前」の状態には、後でフォーカスを戻すことができるように十分な情報を含める必要があります。

説明のために、住所と都市の2つのデータ入力フィールドがあるとします。ViewModelにはそれぞれのプロパティがあり、Viewには対応するViewModelプロパティにバインドされたそれぞれのTextBoxがあります。

ユーザーが[住所]フィールドに値を入力し、[都市]フィールドをクリックした例を見てみましょう。デフォルトのUpdateSourceTrigger.LostFocus動作を使用しているため、アドレステキストボックスがフォーカスを失ったときにアドレス変更が保存されます。これまでのところ、これにアプローチする方法について3つの異なるアイデアがありますが、それらのいずれかを機能させる方法を知るためのWPFについての十分な詳細がわかりません。

  1. MVVMスタイルのデータバインディングを忘れて、編集コントロールのLostFocusイベントをフックする(または、アタッチされた動作を追加するか、TextBoxをラップするカスタムコントロールを作成するなど)ことができます。LostFocusイベントハンドラーで、イベントの送信者への参照を含む元に戻るフレームを作成できます。後で、元に戻す後、参照を保存したコントロールにフォーカスします。これはおそらくWinFormsで行ったことですが、WPFでは、ViewModelパターンに固執したいと思います。他に何もない場合でもテストしやすいように、ジャーナルロジックをViewよりもViewModelに配置したいと思います。したがって、このオプションは私の最初の選択肢ではありません。

  2. 私のViewModelのプロパティセッターでは、設定されているViewModelプロパティの名前(この例では「Address」)をキャプチャし、その名前を元にたりフレームに保存できます。後で、元に戻すで、ビュー内のすべてのコントロールを繰り返し処理して、Addressという名前のプロパティにバインドされているものがある最初のコントロールを探すことができました。そのようなコントロールを見つけたらすぐに焦点を合わせます。同じViewModelプロパティに複数のコントロールがバインドされているとは思わないので、これで十分です。問題は、これにはバインディング式を掘り下げる必要があるということです。これは、私には方法がわかりません。(また、リファクタリングすると壊れてしまう可能性のある、より多くの名前ベースの遅延バインディングが導入されます。)

  3. 私のViewModelが変更を元に戻るスタックに追加すると、(インターフェイスを介して)Viewレイヤーに、どのコントロールにフォーカスがあるかを認識しているMementoを作成するように要求できます。Undoで、ジャーナルはViewにそのMementoを復元するように要求します。ここでの問題は、ViewModelのプロパティが設定され、元に戻るフレームを追加するまでに、キーボードのフォーカスがすでにCity TextBoxに移動しているため、「mementoの作成」は「どこにあるか」よりも難しい必要があることです。現在のキーボードフォーカスは今」であり、そのトリックを達成する方法がわかりません。

上記のいずれかを機能させるための提案がありますか、またはよりうまく機能する可能性のある代替アプローチがありますか?

4

1 に答える 1

1

私はあなたの2番目のアプローチから始めます。ただし、バインディングリストを掘り下げる代わりに、コントロールのハイライトプロパティをVMプロパティにハードコーディングします。

たとえば、これは私のVMです。

public class VM
{
    public double Price { get; set; }
    public bool PriceHighlighted { get; set; }
}

次に、PriceプロパティをTextBoxにバインドし、TextBoxの背景をPriceHighlightedにバインドします(値コンバーターを使用)。これで、VMはビューの反応を完全に制御できます。ユーザーが「元に戻す」を実行すると、VMは、強調表示するものを除くすべてのxxxHightlightedをfalseに設定できます。

于 2009-05-17T15:21:52.733 に答える