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

  • Boiler Room

    Boiler Room

    10 Mayıs 2012
  • Charles Griffin Gibson

    Charles Grif

    26 NİSAN 2006
  • YAN TV

    YAN TV

    20 EKİM 2011