2012-02-10 100 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; } 
    } 
}