IndexOutOfRange 显然不是

IndexOutOfRange when it's clearly not

抱歉,标题并没有真正描述问题,但这是一个非常奇怪的问题。

为了确保我没有犯任何愚蠢的错误,我使用断点来跟踪发生的一切..

基本上,我在 class 中有此代码,它继承自 ObservableCollection<T>:

var n = new MyClass();
int startIndex = 0; // parameter
int length = 2;  // parameter

for (int i = 0; i < length; i++)
{
    n.Text += this[startIndex].Text;
    this.RemoveAt(startIndex);
}

this.Insert(n);

执行代码时,我的collection有3个项目;循环是这样的:

  1. n.Text += "some string successfully gotten from this[startIndex]"
  2. this.RemoveAt(startIndex)
  3. n.Text += "some other string successfully gotten from this[startIndex]"
  4. 异常:IndexOutOfRange。

我已成功获取该项目,但在尝试删除它时出现错误。我迷路了。

非常感谢任何帮助!

提前致谢。

编辑 1

我试过了,结果一样。

var toRemove = this.Skip(startIndex).Take(length).ToList();

foreach (var b in toRemove)
{
    this.Remove(b);
    n.Text += b.Text;
}

再一次,当 Removing 一个项目时,我有一个 IndexOutOfRange 异常。
调试时,我的 Collection 有 2 个项目,RemoveAt(0) 仍然抛出此异常。

编辑 2

修改this.Items时尝试手动调用OnCollectionChangedIndexOutOfRange 异常在调用 OnCollectionChanged 时触发,但在从 this.Items 中删除项目时不会触发。

for (int i = 0; i < length; i++)
{
    this.OnCollectionChanged(new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Remove, Items[startIndex], startIndex));
    Items.RemoveAt(startIndex);
}

调用this.OnCollectionChanged(new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Reset))后,我也遇到了问题
看起来整个问题都来自 ListBox。我会尝试使用绑定和其他东西,然后报告。

  1. 我不建议在循环中写this.RemoveAt(startIndex);,有时当可观察集合枚举在循环内发生变化时是不行的,所以我肯定会把它从循环中取出来
  2. 看来您已经实现了 Obs.Coll 的插入实现。也许问题就在那里

UPD

我认为你的问题在于糟糕的设计。你说你的 class 继承自 observable collection,那这是什么?尝试更好的设计并在集合之外定义方法 class,因为它假装你的集合至少一直都是 3 个元素

UPD 2

设计仍然很丑陋,但如果你想坚持下去,这里是我所做的并且它有效:

  1. 您的集合定义(不推荐这样做)

    public class MyObs : ObservableCollection<MyClass> {
      public void Fun() {
          var n = new MyClass();
          int startIndex = 0; // parameter
          int length = 2;  // parameter
    
          for (int i = 0; i < length; i++) {
              n.Text += this [startIndex].Text;
              this.RemoveAt(startIndex);
          }
    
          this.Insert(0,n); // PAY ATTENTION THAT I INSERT AT 0 !
      }
    }
    
    public class MyClass {
      public string Text { get; set; }
    
      public override string ToString() {
          return Text;
      }
    }
    
  2. 那么你的XAML:

    <ListBox ItemsSource="{Binding MyCollection}"/>
    
  3. 那么你的报关码:

    public MyObs MyCollection { get; set; }
    
  4. 然后初始化处理:

    MyCollection = new MyObs();
    MyCollection.Add(new MyClass() {Text = "Item 1"});
    MyCollection.Add(new MyClass() { Text = "Item 2" });
    MyCollection.Add(new MyClass() { Text = "Item 3" });
    
    MyCollection.Fun();
    

您的插入内容似乎有问题

我想问题出在您在此处引用了已删除的索引:

var toRemove = this.Skip(startIndex).Take(length).ToList();
foreach (var b in toRemove)
{
    this.Remove(b);        <<<  removed
    n.Text += b.Text;      <<<  referencing the removed
}

这样,显然你遇到了描述的错误。反转 n.text 的顺序并删除。

我找到了解决方案。心情不好

基本上,每次 ObservableCollection 更改时都会触发 SelectionChanged,尝试做一些事情并遇到错误。问题是,Stacktrace 中没有任何内容导致了这个想法。

很抱歉浪费您的时间(考虑到评论/答案是好的),请继续。