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

  • Disney Pets and Animals

    Disney Pets

    29 ŞUBAT 2012
  • SomeOne Pro

    SomeOne Pro

    25 EKİM 2013
  • TheDamnWreckless

    TheDamnWreck

    12 Temmuz 2010