替换 ObservableCollection中的项目时出现 ArgumentOutOfRangeException
我正在为 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);
}
}
I'm working on a Refresh() extension method for ObservableCollection which adds, removes or replaces items based on a matching key (this means when bound to a DataGrid the grid doesn't re-scroll and items don't change their position unless they were removed).
Problem is when I replace items in the ObservableCollection the last item throws an ArgumentOutOfRangeException, what am I missing here?
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);
}
}
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
你把旧的和新的搞错了。这:
应该是这样:
当前您正在寻找新值的索引,该索引将为-1...
You've got Old and New the wrong way round. This:
should be this:
Currently you're looking for the index of the new value, which will be -1...