1

実際のユーザー生成データとそれに依存するデータの両方があります (グリッドの Dupe 値を示すために使用される UniformGrid セルの背景色のように、グリッドの ObservableCollection から INotifyPropertyChanged が発生するたびに計算されます)。モデル内で相互に依存するオブジェクトは他にもあります。現在、デシリアライズされると、モデル クラス内のオブジェクトの順序に応じて、一部の依存オブジェクトは正しく更新され、一部は正しく更新されません。(私は MFC プログラミングから来て、ファイルをロードした後に UpdateData() を呼び出し、すべての DDX コントロールを一度に設定することに慣れています。)

コードのその後の変更でバグが発生しやすく、非常にぎこちなく感じます。これは、WPF の多くの場合と同様です。簡単なタスクを達成したい場合は、すぐに完了します。特定の何かが必要な場合は、必要以上に複雑になります。問題に対処するための良い方法はありますか?

4

1 に答える 1

1

あなたの主な問題は、懸念の正しい分離であるようです。WPF と MVVM は、Windows 開発の従来の方法とはかなり異なります。

最初に、ここで何かを整理しましょう。用語との混乱かもしれませんが、言及します。

MVVM では、モデルはデータの保存に使用されません。

データの保持に使用できますか? はい。 データを保持するために使用する必要がありますか? いいえ。

データの保持と変換はビューモデルの仕事です。モデルの仕事はコンジットとして機能することであり、データを取得します (つまり、リポジトリから取得したり、WCF サービスとの通信を制御したりします)。モデルがデータを保持している場合、ビューがモデルにバインドされることを意味しますが、これは間違っています。

あなたが話しているデータの一部は、ビューにも保持する必要があります。何かが重複しているかどうかの判断は、ビューモデルで、場合によってはモデルでも判断できます (モデルはビジネス ルールを適用し、通過するデータにフラグを付けることができます)。複製に表示する色はビューの責任です。その色がビジネス ルールによって決定されない限り、ビューモデルに移動できます。

ObservableCollection にバインドしています。これは、DataGrid のようなリピーター タイプのコントロールを使用していることを示しています。この場合、各行は他の行を認識しません。ある行のデータ オブジェクトからプロパティ変更イベントを発生させた場合、別の行はそれをまったく認識しないため、それらの変更に基づいてレンダリング方法を変更することはできません。このような場合、関連する行のデータをオブザーバー パターンの方法で調整する必要があります。

このような相互依存関係がある場合、実際の各データ オブジェクトを、ファサードとして機能する別の軽量オブジェクトにラップするのが普通です。これを、各行のデータ オブジェクトにビューモデルがあると呼ぶ人もいます。たとえば、単純な Customer オブジェクトは次のとおりです。

public class Customer
{
    public string FirstName {get; set;}

    public string Surname {get; set;}
}

これをビューモデルの ObservableCollection に保存すると、ラップできます。

public class CustomerWrapper
{
    private Customer _customer;
    public CustomerWrapper (Customer customer)
    {
        _customer = customer;
    }

    public bool HasRelation{get;set;}

    public Customer Customer { get {return _customer;}}
}

Customer オブジェクト間の相互依存性を示したい場合 (たとえば、それらがファミリの一部である場合) HasRelation、CustomerWrapper オブジェクトが作成されたら、プロパティを設定するだけです。

var myCustomerList = GetMyCustomers();
foreach (var customer in myCustomerList)
{
    myObservableCollection.Add(new CustomerWrapper(customer) 
    { 
        HasRelation = myCustomerList.Where(p => string.Equals(p.Surname, customer.Surname).Count() > 1) 
    }); 
}

リピーター コントロールを ObservableCollection にバインドすると、HasRelation プロパティを使用して UI の色などを制御できます。

これは不自然な例であり、簡潔にするために意図的に省略していることに注意してください。ビューモデルが各 Customer オブジェクトのプロパティ変更イベントをサブスクライブしている場合、必要に応じて CustomerWrapper オブジェクトを更新できます。相互依存関係の状態は、データを表示するたびに判断できるため、データと共にリポジトリに保存する必要はありません。私が省略したことの 1 つは、FirstName および Surname プロパティをラップすることでした。それらのラッパー プロパティを配置することも、XAML のバインディングでパスを使用して、ネストされたオブジェクトにドリルダウンすることもできます。

于 2013-03-28T11:40:30.057 に答える