【问题标题】:ArgumentOutOfRangeException when replacing items in an ObservableCollection<T>替换 ObservableCollection<T> 中的项目时出现 ArgumentOutOfRangeException
【发布时间】:2009-11-02 06:19:22
【问题描述】:

我正在研究 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);
    }
}

【问题讨论】:

    标签: c# linq silverlight observablecollection


    【解决方案1】:

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

    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...

    【讨论】:

      猜你喜欢
      • 2014-07-07
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-07-04
      • 2013-01-01
      • 2012-11-14
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多