2013-10-15 74 views
2

我有一个MVVM应用程序,并且有数据将网格绑定到可观察集合。集合排序,像这样:将可观察对象的事件引发到容器

public ObservableCollection<MyObject> MyData 
{ 
    get 
    { 
     return _myData; 
    } 
    set 
    { 
     _myData = new ObservableCollection<MyObject>(value.OrderByDescending(s => s.DateParam)); 
     RaisePropertyChanged(() => MyData); 
    } 
} 

当我添加一个条目,这工作得很好,但是,它有可能是日期MyObject.DateParam将发生变化。尽管如图所示,对象和集合都引发NotifyPropertyChanged,但它不会更新。我的解决方法如下:

SelectedDataEntry.DateParam = DateTime.Now; 
MyData = MyData; 

请有人告诉我,有一个很好的方法来做到这一点。

+0

你更新dateParam之后更新的ObservableCollection? – Sasha

+0

我真的不明白这个问题,正如你所看到的,我这样做;但问题是如何在没有的情况下实现这一目标。 –

+0

等一下,我正在处理它;) – Marc

回答

1

你的问题不是关于如何提供ObservableCollection的更改事件,而只是提供一个有序的可观察集合,该集合响应ObservableCollections项目的INotifyPropertyChanged

我推荐使用自定义集合,它实现INotifyCollectionChanged。您请求的功能不受ObservableCollection的支持,也不受WPF的CollectionViewSource的支持,WPF的内部解决方案用于排序和过滤集合。

这里是我的实现,我没有测试它,但你应该按预期工作:

/// <summary> 
/// ObservableCollection, supporting sorting of items 
/// which automatically refreshes when items notify property changes. 
/// </summary> 
/// <typeparam name="T">Item type</typeparam> 
public sealed class SortableObservableCollection<T> : INotifyCollectionChanged, ICollection<T> 
{ 
    private readonly IComparer<T> _comparer; 

    private readonly List<T> _innerItems; 

    public SortableObservableCollection(IComparer<T> comparer) 
    { 
     _comparer = comparer; 
     _innerItems = new List<T>(); 
    } 

    public SortableObservableCollection(IEnumerable<T> collection, IComparer<T> comparer) 
    { 
     _comparer = comparer; 
     _innerItems = new List<T>(collection); 
    } 

    private void Item_PropertyChanged(object sender, PropertyChangedEventArgs e) 
    { 
     Sort(); 
    } 

    public void Sort() 
    { 
     _innerItems.Sort(_comparer); 
    } 

    public event NotifyCollectionChangedEventHandler CollectionChanged; 

    private void RaiseAdd(T newItem) 
    { 
     if (CollectionChanged != null) CollectionChanged(this, new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Add, newItem)); 
    } 

    private void RaiseRemoved(T oldItem) 
    { 
     if (CollectionChanged != null) CollectionChanged(this, new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Remove, oldItem)); 
    } 

    private void RaiseReset() 
    { 
     if (CollectionChanged != null) CollectionChanged(this, new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Reset)); 
    } 

    public IEnumerator<T> GetEnumerator() 
    { 
     return _innerItems.GetEnumerator(); 
    } 

    IEnumerator IEnumerable.GetEnumerator() 
    { 
     return GetEnumerator(); 
    } 

    public void Add(T item) 
    { 
     // Subscribe to items change notification 
     var inpc = item as INotifyPropertyChanged; 
     if (inpc != null) inpc.PropertyChanged += Item_PropertyChanged; 
     _innerItems.Add(item); 
     Sort(); 
     RaiseAdd(item); 
     RaiseReset(); 
    } 

    public void Clear() 
    { 
     foreach (var innerItem in _innerItems) 
     { 
      var inpc = innerItem as INotifyPropertyChanged; 
      if (inpc != null) inpc.PropertyChanged -= Item_PropertyChanged; 
     } 
     _innerItems.Clear(); 
     RaiseReset(); 
    } 

    public bool Contains(T item) 
    { 
     return _innerItems.Contains(item); 
    } 

    public void CopyTo(T[] array, int arrayIndex) 
    { 
     _innerItems.CopyTo(array, arrayIndex); 
    } 

    public bool Remove(T item) 
    { 
     // Unsubscribe from item's change notification 
     var inpc = item as INotifyPropertyChanged; 
     if (inpc != null) inpc.PropertyChanged -= Item_PropertyChanged; 
     var removed = _innerItems.Remove(item); 
     if (!removed) return false; 

     Sort(); 
     RaiseRemoved(item); 
     RaiseReset(); 

     return true; 
    } 

    public int Count { get { return _innerItems.Count; }} 

    public bool IsReadOnly { get { return false; } } 
} 

它基本上包装了List<T>并引发该事件作为对根据操作的ObservableCollection<T>Add(T),Remove(T)Clear())。另外,当项目添加或删除时,它执行Sort() ing操作,并订阅每个项目的INotifyPropertyChanged事件以在项目发生更改时执行排序。请注意,每种类型都会引发一个集合Reset。这不是一个非常高效的解决方案,但您可以通过实施自定义排序操作​​根据您的需求对其进行优化。

0

为什么不创建观察到的集合,如:

private ObservableCollection<MyObject> _myData = new ObservableCollection<MyObject>(); 
public ObservableCollection<MyObject> MyData 
{ 
    get{ return _myData;} 
} 

然后例如

MyData[0].DateParam = DateTime.Now; 
MyData.OrderByDescending(s => s.DateParam); 
相关问题