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

  • CorridorDigital

    CorridorDigi

    17 Mayıs 2010
  • DudeFromUkraine

    DudeFromUkra

    7 Ocak 2008
  • Michael Zhang

    Michael Zhan

    8 EYLÜL 2012