SORU
10 AĞUSTOS 2009, PAZARTESİ


MVVM Senkronize Koleksiyonları

C eşleşen ModelView nesneleri koleksiyonu ile senkronize Model nesnelerin toplanması için standart bir yoludur# ve WPF? Aşağıdaki iki koleksiyonları senkronize sadece birkaç elma var ve tüm hafıza onları tutabilirim varsayarak devam edeceğini sınıfı bir tür arıyorum.

Bunu söylemek için başka bir yol, eğer Elma toplama Elma eklersem bir AppleModelView AppleModelViews koleksiyona sahip olmak istiyorum emin olmak istiyorum. Her koleksiyon' CollectionChanged olay. dinleyerek kendim yazabilirim Bu benden daha akıllı "doğru yol" yapmak. tanımlı olan ortak bir senaryo gibi görünüyor

public class BasketModel
{
    public ObservableCollection<Apple> Apples { get; }
}

public class BasketModelView
{
    public ObservableCollection<AppleModelView> AppleModelViews { get; }
}

CEVAP
1 ŞUBAT 2010, PAZARTESİ


Tembel, otomatik güncelleme koleksiyonları inşa kullanın:

public class BasketModelView
{
    private readonly Lazy<ObservableCollection<AppleModelView>> _appleViews;

    public BasketModelView(BasketModel basket)
    {
        Func<AppleModel, AppleModelView> viewModelCreator = model => new AppleModelView(model);
        Func<ObservableCollection<AppleModelView>> collectionCreator =
            () => new ObservableViewModelCollection<AppleModelView, AppleModel>(basket.Apples, viewModelCreator);

        _appleViews = new Lazy<ObservableCollection<AppleModelView>>(collectionCreator);
    }

    public ObservableCollection<AppleModelView> Apples
    {
        get
        {
            return _appleViews.Value;
        }
    }
}

Aşağıdaki ObservableViewModelCollection<TViewModel, TModel> kullanarak:

namespace Client.UI
{
    using System;
    using System.Collections.Generic;
    using System.Collections.ObjectModel;
    using System.Collections.Specialized;
    using System.Diagnostics.Contracts;
    using System.Linq;

    public class ObservableViewModelCollection<TViewModel, TModel> : ObservableCollection<TViewModel>
    {
        private readonly ObservableCollection<TModel> _source;
        private readonly Func<TModel, TViewModel> _viewModelFactory;

        public ObservableViewModelCollection(ObservableCollection<TModel> source, Func<TModel, TViewModel> viewModelFactory)
            : base(source.Select(model => viewModelFactory(model)))
        {
            Contract.Requires(source != null);
            Contract.Requires(viewModelFactory != null);

            this._source = source;
            this._viewModelFactory = viewModelFactory;
            this._source.CollectionChanged  = OnSourceCollectionChanged;
        }

        protected virtual TViewModel CreateViewModel(TModel model)
        {
            return _viewModelFactory(model);
        }

        private void OnSourceCollectionChanged(object sender, NotifyCollectionChangedEventArgs e)
        {
            switch (e.Action)
            {
            case NotifyCollectionChangedAction.Add:
                for (int i = 0; i < e.NewItems.Count; i  )
                {
                    this.Insert(e.NewStartingIndex   i, CreateViewModel((TModel)e.NewItems[i]));
                }
                break;

            case NotifyCollectionChangedAction.Move:
                if (e.OldItems.Count == 1)
                {
                    this.Move(e.OldStartingIndex, e.NewStartingIndex);
                }
                else
                {
                    List<TViewModel> items = this.Skip(e.OldStartingIndex).Take(e.OldItems.Count).ToList();
                    for (int i = 0; i < e.OldItems.Count; i  )
                        this.RemoveAt(e.OldStartingIndex);

                    for (int i = 0; i < items.Count; i  )
                        this.Insert(e.NewStartingIndex   i, items[i]);
                }
                break;

            case NotifyCollectionChangedAction.Remove:
                for (int i = 0; i < e.OldItems.Count; i  )
                    this.RemoveAt(e.OldStartingIndex);
                break;

            case NotifyCollectionChangedAction.Replace:
                // remove
                for (int i = 0; i < e.OldItems.Count; i  )
                    this.RemoveAt(e.OldStartingIndex);

                // add
                goto case NotifyCollectionChangedAction.Add;

            case NotifyCollectionChangedAction.Reset:
                Clear();
                for (int i = 0; i < e.NewItems.Count; i  )
                    this.Add(CreateViewModel((TModel)e.NewItems[i]));
                break;

            default:
                break;
            }
        }
    }
}

Bunu Paylaş:
  • Google+
  • E-Posta
Etiketler:

YORUMLAR

SPONSOR VİDEO

Rastgele Yazarlar

  • 3biblecom

    3biblecom

    23 NİSAN 2011
  • 3dmmfavs

    3dmmfavs

    29 Kasım 2009
  • efaustus9

    efaustus9

    16 HAZİRAN 2006