2012-02-10 115 views
0

我一直在與MVVM,不知道如何使用的ObservableCollection 的綁定到的ItemsSource在雙向?MVVM的ObservableCollection綁定雙向

例如,我有一個名爲SmartDraw的自定義繪圖用戶控件,其中ItemsSource引用自定義圖形的列表,並將其綁定到View模型中的ObservableCollection圖形。

如果我在視圖模型添加CustomGraphic,該的ItemsSource在SMARTDRAW就會知道是加法CustomGraphic的,然後做一些其他函數調用。這是正常的。

然而,SMARTDRAW也是畫布其使得用戶能夠使用鼠標繪製在其上的圖形。 CustomGraphic的數量將根據用戶繪圖而改變。那麼,我怎麼能知道UI(SmartDraw)更改了ObservableCollection?

這裏是我的代碼:

視圖模型:

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

太謝謝你了。

+0

您可以添加一些關於用戶控件的更多信息。目前還不清楚是否有事件可以讓您跟蹤由於用戶操作而添加CustomGraphic項目的時間。 – AxelEckenberger 2012-02-10 08:42:56

+0

在ObservableCollection <>的雙向綁定中,我如何知道ViewModel中的集合已更改? – user1184598 2012-02-16 01:51:48

+0

看到anser ......但我不確定這是你要求的。 – AxelEckenberger 2012-02-16 10:21:38

回答

0

這不知道是否回答你的問題......但在這裏是你將如何跟蹤總體變化可觀察集合。

要檢測對可觀察集合的更改(不會更改集合中項目的屬性),請訂閱事件ObservableCollection

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; } 
    } 
}