0

元に戻す/やり直し機能を備えた WPF アプリケーションがあります。データベースとのやり取りには EF を使用します。

UI がいくつかのプロパティを変更したときに通知されるより良いアプローチまたはパターンがあるかどうかを知りたいです。

私が現在使用しているアプローチは次のとおりです。

  • EF にクラスを生成させます。例えば:

    public partial class Page: IObjectWithChangeTracker, INotifyPropertyChanged
    {
    #region Primitive Properties
    
    [DataMember]
    public string title
    {
        get { return _title; }
        set
        {
            if (_title != value)
            {
                _title = value;
                OnPropertyChanged("title");
            }
        }
    }
    private string _title;
    
    ...
    
  • 次に、クラスの非生成部分に、UI 用の別のプロパティを追加します。この特定のケースでは、プロパティは WPF TextBox にバインドされています。

    public partial class Page
    {
    public Page()
    {
        ((INotifyPropertyChanged)this).PropertyChanged += Page_PropertyChanged;
    }
    
    void Page_PropertyChanged(object sender, PropertyChangedEventArgs e)
    {
        switch (e.PropertyName) {
        case "title":
            OnPropertyChanged("titleUI");
            break;
        }
    }
    
    public string titleUI
    {
        get { return title; }
        set
        {
            if (value == title)
                return;
            string oldValue = title;
            title = value;
            UndoRedo.PushAtomic(
                () => title = oldValue, 
                () => title = value,
                "change page title");
        }
    }
    
    ...
    

以前はこの目的で FrameworkElement.SourceUpdated をリッスンしていましたが、MVVM 設計パターンにより厳​​密に従うためにこのアプローチを断念しました。

より良い、またはより簡単なアプローチはありますか?

編集: TextBox をプロパティに直接バインドしない理由はtitle、プロパティが TextBox 以外のものによって更新されるたびに、元に戻す/やり直しスタックに追加したくないからです。また、EF ObjectContext がエンティティを具体化するとき、値はセッターによって割り当てられ、それを元に戻す/やり直すスタックにも追加したくありません。

編集2:私はこの質問のためにSOをちょっとあきらめました。できれば削除します。たとえば、私のコードが真の MVVM ではないというコメントが、目前の問題とどのように関係しているかを理解できません。エンティティ クラスをいわゆる ViewModel クラスから厳密に分離するかどうかにかかわらず、UI からの更新を「インターセプト」する方法を見つける必要があります。私は閉鎖に投票しました。これがどこにも行かないと私のように感じたら、同じことをしてください.

4

2 に答える 2

1

wpf textbox には組み込みの元に戻す/やり直しがあります。そのため、viewmodel プロパティを mode=twoway でバインドするだけで、ビューモデルとビューは常に同期され、テキストボックスはやり直しの取り消しを処理します。私は何かが恋しいですか?

于 2012-07-13T10:35:59.943 に答える
0

あなたが望んでいた答えではありませんが、私は Unity のようなものを見たいと思います:

http://blogs.msdn.com/b/agile/archive/2011/03/21/interception-in-silverlight-demo.aspx

これは Silverlight の投稿です (ただし、WPF でも動作します)。基本的に、モデルのインターセプターを作成し、プロパティのゲッター/セッターにコードを挿入できます。このようにして、プロパティを再実装することなく、N レベルの取り消し/やり直し処理コードを呼び出すことができます。

それでも、標準のビューモデルはモデルをカプセル化するため、ビューモデルよりもリッチモデルのように見えます

モデルのすべてのプロパティに対して、そのコードを使用して追加のプロパティ ゲッター/セッターを記述する必要はありません。

(仮想メソッドインターセプターを示していますが、インスタンスインターセプターを使用することは可能です。これは機能すると思いますが、インターセプターとそれらが「リッスン」するスコープについてのポイントをリッスンします)

編集:

本当に質問に答えてなくてごめんなさい

以下にいくつかの提案を示します。

EF がエンティティ クラスを基本クラスから派生させるかどうかはわかりませんが、それは 1 つのことです。基本クラスで PropertyChanged イベントをフックし、それに応じて処理するだけです。Dictionary<string, object>「古い」値を追跡し、元に戻すを処理するために、ベースを維持することができます

オブジェクトをマテリアライズする EF について少し理解しています。オブジェクトがマテリアライズされている間、プロパティの変更を無視するように指示するフラグを UndoRedo スタックに追加できませんか?

元に戻す/やり直し情報をバイパスするようにスタックに指示するために、部分エンティティ クラスでオーバーライドできるいくつかのメソッドが必要です。

于 2012-07-13T10:05:35.310 に答える