[英]Exception being thrown when adding an item to a ListCollectionView
當我運行以下測試時,我收到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
嗎?
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
(?!),所以您已手動指定了占位符AtBeginning
新項目。
我不確定,但是我認為您應該使用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();
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.