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

  • dope2111

    dope2111

    29 HAZİRAN 2009
  • Smith Micro Graphics

    Smith Micro

    15 Mayıs 2008
  • TomSka

    TomSka

    30 Mayıs 2006