2

だから、OrderModel と OrderViewModel があるとしましょう。ビューモデルとモデルの両方にサプライヤー、注文日などのプロパティがあり、それらはリンクされています。これに関する例を見て、セッター/ゲッターを書くという点で多少重複していますが、十分に簡単に思えます。

OrderDetails をどうすればよいでしょうか。私のモデルでは、リストがあります。

OrderDetail の OrderDetailViewModel はありますか? もしそうなら、OrderViewModel はそれをどのように提供しますか? ObservableCollectionとして?もしそうなら、どうやってそれを元のリストと同期させますか?

これは、まともな例を見たことがないところです。誰かが私に指摘できるものがあれば、私はそれを感謝します. 私はMVVMの概念に嘘をついていますが、オーバーヘッドが非常に大きいことに気付き始めています。ViewModel でモデル パーツも処理しないのはなぜですか。日々の LOB アプリでは、真の MVVM が必要と思われるすべてのコードを保証するために、この 2 つの間に実際にそれほど大きな違いがあるのでしょうか?

4

3 に答える 3

1

次のようなものを使用して、ObservableCollections をモデルとビュー モデルの間で同期させることができます。

/// <summary>
/// Keeps one collection synchronised with another.
/// </summary>
/// <typeparam name="Source">The type of the source items.</typeparam>
/// <typeparam name="Destination">The type of the destination items.</typeparam>
public class CollectionSync<Source, Destination>
{
    private readonly Func<Source, Destination> _destItemFactory;
    private readonly Action<Destination>       _destItemRemover;

    private readonly IList<Destination> _destList;
    private readonly IList<Source>      _sourceList;

    /// <summary>
    /// Initializes a new instance of the <see cref="CollectionSync&lt;Source, Destination&gt;"/> class.
    /// </summary>
    /// <param name="sourceList">The source list.</param>
    /// <param name="destList">The destination list.</param>
    /// <param name="destItemFactory">Factory method which creates a Destination for a given Source.</param>
    /// <param name="destItemRemover">Method called when a Destination is removed.</param>
    public CollectionSync(IList<Source> sourceList,
                          IList<Destination> destList,
                          Func<Source, Destination> destItemFactory,
                          Action<Destination> destItemRemover)
    {
        _destItemFactory = destItemFactory;
        _destItemRemover = destItemRemover;
        _sourceList = sourceList;
        _destList = destList;

        ((INotifyCollectionChanged) _sourceList).CollectionChanged += SourceCollection_CollectionChanged;

        PopulateWithAllItems();
    }

    private void PopulateWithAllItems()
    {
        foreach (Source sourceItem in _sourceList)
            _destList.Add(_destItemFactory(sourceItem));
    }

    private void SourceCollection_CollectionChanged(object sender, NotifyCollectionChangedEventArgs args)
    {
        switch (args.Action)
        {
            case NotifyCollectionChangedAction.Add:
                OnItemsAdded(args.NewStartingIndex, args.NewItems);
                break;
            case NotifyCollectionChangedAction.Remove:
                OnItemsRemoved(args.OldStartingIndex, args.OldItems);
                break;
            case NotifyCollectionChangedAction.Reset:
                OnItemsReset();
                break;
            case NotifyCollectionChangedAction.Move:
            case NotifyCollectionChangedAction.Replace:
                throw new NotImplementedException();
        }
    }

    private void OnItemsReset()
    {
        _destList.Clear();
        PopulateWithAllItems();
    }

    private void OnItemsRemoved(int index, ICollection items)
    {
        int itemCount = items.Count;
        for (int i = 0; i < itemCount; i++)
        {
            Destination removed = _destList[index];
            _destList.RemoveAt(index);
            if (_destItemRemover != null)
                _destItemRemover(removed);
        }
    }

    private void OnItemsAdded(int index, IList items)
    {
        int itemIndex = index;
        foreach (Source item in items)
        {
            // Add to Items collection
            _destList.Insert(itemIndex, _destItemFactory(item));
            itemIndex++;
        }
    }
}

Order/OrderDetails の例を取り上げると、Order ビュー モデルでは、次のように 2 つの ObservableCollections を接続します。

_modelToViewModelSync = new CollectionSync<IOrderDetail, OrderDetailViewModel>(
    orderDetailModels,                 // the list of your order details models
    OrderDetails,                      // the list of order details view models exposed by the Order view model
    x => new OrderDetailViewModel(x),  // factory method to create a view model
    null);                             // do something here if you care when your view models are removed
于 2009-05-01T20:04:37.190 に答える
1

これが必要なもののようです: http://jonas.follesoe.no/SpeakingAtMSDNLiveNextMonth.aspx

グーグルでの翻訳は、これを講演の要約として示しています:

この秋にリリースされた Silverlight 2 は、Silverlight 2 に基づいてリッチ インターネット アプリケーション (RIA) を作成したい開発者にとって優れた基盤を築きます。ネット。このセッションでは、Silverlight 2 の開発と、データ中心のビジネス アプリケーションのプラットフォームとして Silverlight 2 を選択する利点について詳しく説明します。このセッションでは、セキュリティで保護された WCF サービスを介したデータ アクセス、Model-View-View Model パターン (MVVM) を使用してコードを構造化する方法、コードを作成する方法、デザイナーが使用できる方法、開発者向けの easy-Blend のヒントなどについて説明します。 . セッションは、プレゼンテーションの後にコードが利用できるダイブログ アプリケーションを中心に構築されます。

ただし、それまでの間、Jonas はすでにここで MVVM について話しました。

http://jonas.follesoe.no/YouCardRevisitedImplementingTheViewModelPattern.aspx

于 2009-03-13T06:54:52.383 に答える
0

「別のビューモデルが必要ですか」という質問に対する私の答えは次のとおりです。ビューがモデルデータを表示するだけであれば、注文に直接バインドしても害はありません。このために ViewModel を作成するのは非常に冗長です。ViewModel を作成する必要があるのは、表示する必要がある「注文の詳細」画面にロジックまたは状態があるときです。それをモデルに追加する代わりに、その時点で ViewModel を作成します。

これらのアイテムの同期を維持する限り、GraemeF と同様に、リフレクションを使用して 2 つの値をバインドする Binder クラスを作成しました。モデルとビューモデルのプロパティの同期を維持し、この特定のコレクションのように、他のものの同期を維持するために使用できます。このようにバインダーを作成すると多少のオーバーヘッドがありますが、一度作成すると、機能的な方法でデータの関連付けを指定できるので、非常に便利です。

于 2009-05-01T20:13:07.200 に答える