3

我正在研究 ObservableCollection 的 Refresh() 扩展方法,它根据匹配的键添加、删除或替换项目(这意味着当绑定到 DataGrid 时,网格不会重新滚动并且项目不会改变它们的位置,除非他们被删除)。

问题是当我替换 ObservableCollection 中的项目时,最后一个项目引发 ArgumentOutOfRangeException,我在这里缺少什么?

public static void Refresh<TItem, TKey>(this ObservableCollection<TItem> target, IEnumerable<TItem> source, Func<TItem, TKey> keySelector)
{
    var sourceDictionary = source.ToDictionary(keySelector);
    var targetDictionary = target.ToDictionary(keySelector);

    var newItems = sourceDictionary.Keys.Except(targetDictionary.Keys).Select(k => sourceDictionary[k]).ToList();
    var removedItems = targetDictionary.Keys.Except(sourceDictionary.Keys).Select(k => targetDictionary[k]).ToList();
    var updatedItems = (from eachKey in targetDictionary.Keys.Intersect(sourceDictionary.Keys)
                        select new
                        {
                            Old = targetDictionary[eachKey],
                            New = sourceDictionary[eachKey]
                        }).ToList();

    foreach (var updatedItem in updatedItems)
    {
        int index = target.IndexOf(updatedItem.Old);
        target[index] = updatedItem.New; // ArgumentOutOfRangeException is thrown here
    }

    foreach (var removedItem in removedItems)
    {
        target.Remove(removedItem);
    }

    foreach (var newItem in newItems)
    {
        target.Add(newItem);
    }
}
4

1 回答 1

2

你把旧的和新的弄错了。这:

var updatedItems = (from eachKey in targetDictionary.Keys
                                              .Intersect(sourceDictionary.Keys)
                    select new
                    {
                        Old = targetDictionary[eachKey],
                        New = sourceDictionary[eachKey]
                    }).ToList();

应该是这样的:

var updatedItems = (from eachKey in targetDictionary.Keys
                                              .Intersect(sourceDictionary.Keys)
                    select new
                    {
                        New = targetDictionary[eachKey],
                        Old = sourceDictionary[eachKey]
                    }).ToList();

目前您正在寻找值的索引,它将是-1 ...

于 2009-11-02T07:06:15.563 回答