在CollectionChanged中获取当前通用项item

本文关键字:item CollectionChanged 获取 | 更新日期: 2023-09-27 18:07:30

我有一个继承IEnumerable的自定义集合。

public class MyCollection<T> : IEnumerable<T>   
{
    private ObservableCollection<T> currentList = new ObservableCollection<T>();
    public ObservableCollection<T> Items
    {
        get { return currentList; }  
        set { currentList = value; }
    }
    private List<T> deletedList = new List<T>();
    private List<T> addedList = new List<T>();
    public MyCollection(IEnumerable<T> currentList)
    {
        this.currentList = new ObservableCollection<T>(currentList);
        Items.CollectionChanged+=Items_CollectionChanged;
    }
}

我希望跟踪哪些项目被添加或删除。此外,我的项目在WPF中绑定到一个UI数据网格。如果我绑定到Items而不是MyCollection,则绑定工作正常。但是,我想跟踪添加,删除的项目如下。当我从UI中添加或删除任何项目时,我假设捕获以下事件。

当每一行被添加到DataGrid中时,我希望调用这个函数来保存最后添加的条目。

现在我如何获得当前添加或删除的项目在这个?

private void Items_CollectionChanged(object sender, NotifyCollectionChangedEventArgs e)
{  
    if (e.Action == NotifyCollectionChangedAction.Remove)
    {
        //this doesn't work  ( I List is not assignable to IEnumerable T
        deletedList.AddRange(e.OldItems);
    }
    if (e.Action == NotifyCollectionChangedAction.Add)
    {
        //this doesnt work 
        addedList.AddRange(e.OldItems);
    }
}

我只得到添加或删除的项。

public ObservableCollection<T> GetAddedChanges()
{
    var added = new ObservableCollection<T>();
    addedList.ToList().ForEach(added.Add);
    return added;
}
public ObservableCollection<T> GetDeletedChanges()
{
    var deleted = new ObservableCollection<T>();
    deletedList.ToList().ForEach(deleted.Add);
    return deleted;
}

更新:这里的初始答案是有效的,即Cast()选项,我只能从列表中获取添加的成员并保存它们。

还有一个问题。我让我的服务器返回MyCollection。可悲的是,我的服务器当它反序列化到集合对象时,它会被Items_CollectionChanged的添加事件捕获,因此我添加的列表总是错误地返回添加列表中的2项。

解决方法:

1)在服务器返回后订阅事件而不是MyCollection构造函数。即在另一个StartTracking()中订阅。

2)从服务器得到响应后,清除添加的、删除的列表。

哪一个会更好?还有其他解决方案吗?

这是基本的流程:

UI -> OBservableCollection -> MyCollection(我跟踪添加/删除元素)-> Save to Server ..从服务器获取,我有我的服务器端代码返回MyCollectionwith条目在它。

在CollectionChanged中获取当前通用项item

OldItems不是通用的(它是IList而不是IList<T>),所以您需要转换项目。

:

foreach(T item in e.OldItems)
{
    deletedList.Add(item);
}

或:

deletedList.AddRange(e.OldItems.Cast<T>());

在跟踪添加时,您将需要使用NewItems。顺便说一句,这不会捕获在替换(例如c[0] = <new item>)或重置(例如在调用Clear之后)期间发生的更改。

我也注意到你的GetAddedChanges可以简化(和类似的GetDeletedChanges):

return new ObservableCollection<T>(addedList);

虽然不清楚为什么返回类型需要是ObservableCollection<T>