【问题标题】:Exception being thrown when adding an item to a ListCollectionView将项目添加到 ListCollectionView 时引发异常
【发布时间】:2012-04-07 20:51:09
【问题描述】:

当我运行以下测试时,我得到一个 ArgumentOutOfRangeException:

[TestClass]
public class ReproduceException
{
    [TestMethod]
    public void Doesnt_throw_when_adding_to_grouped_collection()
    {
        var collection = new ListCollectionView(new List<Test>());
        collection.SortDescriptions.Add(new SortDescription("IsTrue", ListSortDirection.Ascending));
        collection.GroupDescriptions.Add(new PropertyGroupDescription("Name"));
        collection.AddNewItem(new Test() { Name = "Bob", IsTrue = false });
        collection.CommitNew();

    }
}

public class Test
{
    public string Name { get; set; }
    public bool IsTrue { get; set; }
}

我得到以下异常:

System.ArgumentOutOfRangeException: Index was out of range. Must be non-negative and less than the size of the collection.
Parameter name: index
at System.ThrowHelper.ThrowArgumentOutOfRangeException()
at System.Collections.ObjectModel.Collection`1.RemoveAt(Int32 index)
at System.Windows.Data.ListCollectionView.CommitNewForGrouping()
at System.Windows.Data.ListCollectionView.CommitNew()

我可能没有以正确的方式使用AddNewItem / CommitNew

【问题讨论】:

    标签: c# .net wpf exception


    【解决方案1】:

    可能的解决方案:

    1) 在添加新项目之前做

     collection.NewItemPlaceholderPosition = NewItemPlaceholderPosition.AtBeginning;
    

    2)基本上尝试在创建分组和排序之前添加项目:

    var collection = new ListCollectionView(new List<Test>());            
    collection.AddNewItem(new Test() { Name = "Bob", IsTrue = false });
    collection.CommitNew();
    
    collection.SortDescriptions.Add(new SortDescription("IsTrue", 
                                              ListSortDirection.Ascending));   
    collection.GroupDescriptions.Add(new PropertyGroupDescription("Name"));
    

    分析:

    在深入研究 .NET Reflector 后,CommitNew() 方法有以下检查:

    // !!! When you've added GroupDescription this.IsGrouping becomes true!
    if (this.IsGrouping)
    {
        this.CommitNewForGrouping();
    }
    

    由于您添加了 GroupDescription,它将提交分组:

    private void CommitNewForGrouping()
    {
        int num;   
    
        // !!! I believe it is None by default
        switch (this.NewItemPlaceholderPosition)
        {
            case NewItemPlaceholderPosition.AtBeginning:
                num = 1;
                break;
    
            case NewItemPlaceholderPosition.AtEnd:
                num = this._group.Items.Count - 2;
                break;
    
            default:
                // !!! Since you've not added groups -1 would be assigned to num
                num = this._group.Items.Count - 1;
                break;
        }
        int index = this._newItemIndex;
        object item = this.EndAddNew(false);
    
        // This method will call RemoveAt(num) where num == -1 in your case
        this._group.RemoveSpecialItem(num, item, false);
        this.ProcessCollectionChanged(new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Add, 
                 item, index));
    
    }
    
    internal void RemoveSpecialItem(int index, object item, bool loading)
    {
         ...
         // will fail since index always -1
         base.ProtectedItems.RemoveAt(index);
         ...
    }
    

    LCV 有私有方法ProcessCollectionChangedWithAdjustedIndex,它在不同的场景中调整索引,但在添加启用分组的新项目时不会调用它,我不知道为什么看起来这是设计使然(?!)所以你有为新项目手动指定占位符 AtBeginning

    【讨论】:

    • 2) 我可以确认在添加项目后添加排序和组是有效的,但不幸的是,我需要能够在设置集合视图后添加新项目,而不是继续添加/删除排序和分组:)
    • 解决方案 1) 成功了!非常感谢。您认为这是预期行为还是错误?
    【解决方案2】:

    我不确定,但我认为您应该使用AddNew() 方法而不是AddNewItem。你将调用CommitNew(),而不调用AddNew(),并且没有开始事务,所以抛出异常。

    AddNewItem() 摘要:Adds the specified object to the collection.

    AddNew() 摘要:Starts an add transaction and returns the pending new item.

    CommitNew() 摘要:Ends the add transaction and saves the pending new item.

    所以,你应该编写下一行代码:

    Test pendingItem = (Test)collection2.AddNew();
    pendingItem.Name = "Bob";
    pendingItem.IsTrue = false;
    collection2.CommitNew();
    

    【讨论】:

    • 我刚刚试过了,不幸的是它抛出了同样的异常
    猜你喜欢
    • 1970-01-01
    • 2015-12-14
    • 1970-01-01
    • 2018-05-16
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-02-10
    相关资源
    最近更新 更多