6

MVVM-Light フレームワークを使用して WPF データベース アプリケーションに取り組んでいます。SimpleIOC を使用して Data Services を挿入しています。ViewModel は XAML ファイルからビューに接続されています。ただし、新しいビュー モデルを開くときは、通常、別のオブジェクトをビュー モデルに渡す必要もあります (データベースから実際の車を取得できるように、CarId の整数を渡すとします)。

現在、InitializeComponent() の後に、ビューでメッセンジャーを使用してこれを渡しています。これは、View Model によってキャッチされます。これは現在のところ機能しますが、いくつかの欠点があります。

まず、ビュー モデルのコンストラクターが呼び出されるまで、メッセージは送信されません。ViewModel に ThisCar オブジェクトの Property があり、ThisCar.Brand を返す Brand という文字列のような二次プロパティがあるとします。

    public const string ThisPersonPropertyName = "ThisCar";
    private Model.Car _thisCar;
    public Model.Car ThisCar
    {
        get
        {
            return _thisCar;
        }

        set
        {
            if (_thisCar== value)
            {
                return;
            }

            RaisePropertyChanging(ThisCarPropertyName);
            _thisCar= value;
            RaisePropertyChanged(ThisCarPropertyName);
        }
    }

    public const string BrandPropertyName = "Brand";
    public string Brand
    {
        get
        {
            return ThisCar.Brand;
        }

        set
        {
            if (ThisCar.Brand == value)
            {
                return;
            }

            RaisePropertyChanging(BrandPropertyName);
            ThisCar.Brand = value;
            RaisePropertyChanged(BrandPropertyName);
        }
    }

コンストラクターが呼び出されたら、View Model コンストラクターで ThisCar を初期化する必要があります。そうしないと、ViewModel が作成されるときに ThisCar.Brand で null エラーが発生します。

ThisCar = new CarObject();

次に、空のオブジェクトに初期化された後、メッセージが呼び出され、車の ID に基づいてデータベースから実際の車を取得します。

ThisCar = webService.GetCar(carId);

ただし、これを行うと、ブランドの OnPropertyChanged を呼び出すものがないため、ブランド プロパティは更新されません。

回避策は 2 つありますが、どちらかというとハックのように感じます。まず、更新が必要なプロパティに対して OnPropertyChanged を手動で呼び出します。2 つ目は、小さなプロパティをすべて削除し、すべてを ThisCar プロパティに直接バインドすることです (つまり、モデルに INotifyPropertyChanged を実装する必要があります)。

私がうるさいだけなのか、それとももっと良い方法があるのか​​教えてください。私がやっている方法はうまくいきますが、私には合いません。ありがとうございました。

4

2 に答える 2

2

わかりました、これが私が思いついたものです。これが恐ろしいアイデアである場合はお知らせください。

依存性注入を使用してビュー モデルを作成しているため、IRepository というインターフェイスを作成しました。実装は次のとおりです。

public interface IRepository
{
    void GetCarId(Action<int> callback);
    void SetCarId(int value);
}

次に、IRepository を継承するクラスを作成します。

public class Repository : IRepository
{
    private int CarId;
    public void GetCarId(Action<int> callback)
    {
        callback(CarId);
    }

    public void setDictionary(int carId)
    {
        CarId = carId;
    }
}

値をリポジトリに渡すために、これを親ビュー モデルに入れます。

 r.SetCarId(13);

そして、新しいビューモデルを受け取るために、これをビューモデルコンストラクターに入れました:

    public View2ViewModel(IChildView i, IRepository r)
    {
        int CarId;
        r.GetCarId((id) => CarId = id);
        thisCar = GetCarFromDatabase(CarId);
    }

これは、MVVM パターンを壊さずに問題を解決するように思えます。使用している IOC コンテナーはすべてのインターフェイス メンバーを staic として作成するため、残りのビュー全体でこのデータを保持します。

これに関する主な問題は、それがグローバル変数のように感じられることですが、これは私が思いつくことができる最高のものです。これが本当に悪い考えかどうか教えてください。ありがとうございました。

于 2013-08-29T21:23:38.997 に答える