我正在为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);
}
}
答案 0 :(得分: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();
目前您正在寻找 new 值的索引,该值为-1 ......