2012-02-10 3 views
0

Я работал с MVVM и задавался вопросом, как использовать ObservableCollection для привязки к ItemsSource в TwoWay?MVVM ObservableCollection Bind TwoWay

Например, у меня есть пользовательский пользовательский чертежный пользовательский интерфейс под названием SmartDraw, в котором ItemsSource ссылается на список пользовательской графики и привязан к Graphics ObservableCollection в Model View.

Если я добавлю CustomGraphic в модель представления, ItemSource в SmartDraw будет знать, что есть добавление CustomGraphic, а затем выполнять некоторые другие вызовы функций. Это нормально.

Однако SmartDraw также является холстом, который позволяет пользователю рисовать графику на нем с помощью мыши. Количество CustomGraphic изменится в соответствии с чертежом пользователя. Итак, как я могу узнать, что ObservableCollection изменен пользовательским интерфейсом (SmartDraw)?

Вот мой код:

ViewModel:

public ObservableCollection<CustomGraphic> Graphics { get; set; } 

Спасибо так много.

+0

Не могли бы вы добавить дополнительную информацию об User Control. Неясно, есть ли события, которые позволяют вам отслеживать, когда элемент CustomGraphic добавлен из-за действия пользователя. – AxelEckenberger

+0

В двухстороннем связывании ObservableCollection <>, как я могу узнать, что коллекция изменена в ViewModel? – user1184598

+0

см. Anser ... однако я не уверен, что это то, о чем вы просите. – AxelEckenberger

ответ

0

Не уверен, отвечает ли это на ваш вопрос ... но вот как вы могли бы отслеживать изменения в наблюдаемой коллекции в целом.

Чтобы обнаружить изменения в наблюдаемой коллекции (не изменяя свойства элементов в коллекции), вы подписываетесь на событие CollectionChangedObservableCollection.

private ObservableCollection<ViewModel> _collection; 
public ObservableCollection<ViewModel> Collection { 
    get { return _collection; } 
    set { 
     if (_collection != value) { 
      // de-register on collection changed 
      if (_collection != null) 
       _collection.CollectionChanged -= this.Collection_CollectionChanged; 

      _collection = value; 

      // re-register on collection changed 
      if (_collection != null) 
       _collection.CollectionChanged += this.Collection_CollectionChanged; 
    } 
} 

private void Collection_CollectionChanged(object sender, NotifyCollectionChangedEventArgs e) { 
    switch (e.Action) { 
    case NotifyCollectionChangedAction.Add: 
      // e.NewItems contains the added items 
    break; 
    case NotifyCollectionChangedAction.Remove: 
      // e.OldItems contains the removed items 
      break; 
     case NotifyCollectionChangedAction.Replace: 
      // e.NewItems contains the new items, 
      // e.OldItems contains the removed items 
      break; 
     case NotifyCollectionChangedAction.Reset: 
      // the collection has been cleared 
      break; 
    } 
} 

Если вам необходимо отслеживать изменения объектов в коллекции вы должны построить расширенный ObservableCollection, что присоединяется к PropertyChanged событиям элементов, а затем поднимает событие, если один из этих свойств изменились.

public class ObservableCollectionEx<TValue> : ObservableCollectionAddRange<TValue> 
{ 

    public ObservableCollectionEx() : base() { } 
    public ObservableCollectionEx(IEnumerable<TValue> values) 
     : base(values) 
    { 
     this.EnsureEventWiring(); 
    } 
    public ObservableCollectionEx(List<TValue> list) 
     : base(list) 
    { 
     this.EnsureEventWiring(); 
    } 

    public event EventHandler<ItemChangedEventArgs> ItemChanged; 

    protected override void InsertItem(int index, TValue item) 
    { 
     base.InsertItem(index, item); 

     var npc = item as INotifyPropertyChanged; 
     if (npc != null) 
     npc.PropertyChanged += this.HandleItemPropertyChanged; 
    } 

    protected override void RemoveItem(int index) 
    { 
     var item = this[index]; 

     base.RemoveItem(index); 

     var npc = item as INotifyPropertyChanged; 
     if (npc != null) 
     npc.PropertyChanged -= this.HandleItemPropertyChanged; 
    } 

    protected override void SetItem(int index, TValue item) 
    { 
     var oldItem = this[index]; 

     base.SetItem(index, item); 

     var npcOld = item as INotifyPropertyChanged; 
     if (npcOld != null) 
     npcOld.PropertyChanged -= this.HandleItemPropertyChanged; 

     var npcNew = item as INotifyPropertyChanged; 
     if (npcNew != null) 
     npcNew.PropertyChanged += this.HandleItemPropertyChanged; 
    } 

    protected override void ClearItems() 
    { 
     var items = this.Items.ToList(); 

     base.ClearItems(); 

     foreach (var npc in items.OfType<INotifyPropertyChanged>().Cast<INotifyPropertyChanged>()) 
     npc.PropertyChanged -= this.HandleItemPropertyChanged; 
    } 


    private void HandleItemPropertyChanged(object sender, PropertyChangedEventArgs args) 
    { 
     if (typeof(TValue).IsAssignableFrom(sender.GetType())) 
     { 
     var item = (TValue)sender; 
     var pos = this.IndexOf(item); 
     this.OnItemChanged(item, pos, args.PropertyName); 
     } 
    } 

    protected virtual void OnItemChanged(TValue item, int index, string propertyName) 
    { 
     if (this.ItemChanged != null) 
     this.ItemChanged(this, new ItemChangedEventArgs(item, index, propertyName)); 
    } 

    private void EnsureEventWiring() 
    { 
     foreach (var npc in this.Items.OfType<INotifyPropertyChanged>().Cast<INotifyPropertyChanged>()) 
     { 
     npc.PropertyChanged -= this.HandleItemPropertyChanged; 
     npc.PropertyChanged += this.HandleItemPropertyChanged; 
     } 
    } 

    public class ItemChangedEventArgs : EventArgs 
    { 
     public ItemChangedEventArgs(TValue item, int index, string propertyName) 
     { 
     this.Item = item; 
     this.Index = index; 
     this.PropertyName = propertyName; 
     } 

     public int Index { get; private set; } 
     public TValue Item { get; private set; } 
     public string PropertyName { get; private set; } 
    } 
} 
Смежные вопросы