2

我有一个 MVVM 应用程序,并将数据绑定到一个可观察的集合。集合排序如下:

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

当我添加一个条目时,这很好用,但是,日期可能MyObject.DateParam会改变。尽管对象和集合都提高了 aNotifyPropertyChanged如图所示,但它不会更新。我的解决方法如下:

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

请有人告诉我有一种更巧妙的方法可以做到这一点。

4

2 回答 2

1

您的问题与其说是引发 an 的更改事件,不如ObservableCollection说是关于如何提供一个有序的可观察集合,该集合响应INotifyPropertyChangedObservableCollections 项目。

我建议使用自定义集合,它实现INotifyCollectionChanged. 您要求的功能不受 WPF 支持ObservableCollection,WPF 也不支持CollectionViewSourceWPF 的内部解决方案,用于对集合进行排序和过滤。

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

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

它基本上包装了 a并在相应的操作 ( , , )上List<T>引发与 a 相同的事件。此外,它在添加或删除项目时执行ing 操作,并订阅每个项目的事件以在项目更改时执行排序。注意,每次排序都会引发一个集合。这不是一个非常高效的解决方案,但您可以通过实现自定义排序操作​​来根据您的需要对其进行优化。ObservableCollection<T>Add(T)Remove(T)Clear()Sort()INotifyPropertyChangedReset

于 2013-10-15T10:36:01.673 回答
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);
于 2013-10-15T11:37:57.593 回答