2016-11-04 70 views
1

这是我的第一个问题。我无法解决这个错误2周。 为了解决注册的问题。 这是我的vb代码。InvalidArgument =''的值不适用于'索引'(''内部编号)

Try 
    For i As Integer = 0 To ListBox1.Items.Count - 1 Step 1 
     For j As Integer = 0 To ListBox2.Items.Count - 1 Step 1 
      If ListBox1.Items(i).ToString().Equals(ListBox2.Items(j).ToString()) = True Then 
       ListBox1.Items.RemoveAt(i) 
      End If 
     Next 
    Next 
Catch ex As Exception 
    MsgBox("LOAD ERROR: " + ex.Message, vbCritical, "ERROR") 
End Try 

错误:

InvalidArgument '20' 的=值是无效的 '索引'(”'是变体光盘。)

项目具有除了这个误差没有问题

回答

1

当我运行你的代码时,我收到了一个不同的异常,参数超出了范围......这是由于在遍历它时删除索引集合中的项目而引起的。例如,我们假设listbox1中有10个项目。如果您在listbox2中找到项目编号1并将其删除,那么现在您在列表框1中只剩下9个项目。问题是,当你进入你的循环时,你告诉它循环10个项目,它仍然会尝试这样做。在某个时候,如果有任何项目被删除,这个循环会抛出一个异常......所以你需要迟早改变它。为了缓解这一点,通过一步,你会从落后删除项目这样的收集:

For i As Integer = ListBox1.Items.Count - 1 to 0 Step -1 

当我运行上面所示变化的代码,它按预期工作,并从ListBox1中的重复的项目。不幸的是,我无法重现你的无效论证异常。奇怪的是,因为通常这种异常在使用列表视图时弹出,而不是列表框。也许你可以编辑你的文章并在你的列表框中添加数据的截图,这样其他人可以更容易地排除故障。

+0

这段代码简单地解决了!另外,Example很容易理解它。谢谢你的建议! – baegopa

3

试试这个:

Dim items = ListBox1.Items.Where(Function(item) ListBox2.Items.Contains(item)).ToList() 
For Each item in items 
    ListBox1.Remove(item) 
Next 
+0

@baegopa这是一个更干净的方式来完成你想要做的事情,也将避免我提到 – soohoonigan

+0

@soohoonigan的ArgumentOutOfRange异常,但它并不教授初学者“编码的内部”。看,我们已经在Linq之前的世界里经历过它。这是什么让我们“知道事情” –

+0

嗯..我试过这个代码。但发生编译错误..谢谢指教 – baegopa

0

正如您从ListBox1项目总数量会下降(显然)项目,但是For循环不尊重这一点。一个For循环将只有To的右侧设置一次,这是在第一次迭代之前完成的。

你正在做什么其实是等于这个:

Dim a As Integer = ListBox1.Items.Count - 1 
For i As Integer = 0 To a Step 1 

    Dim b As Integer = ListBox2.Items.Count - 1 
    For j As Integer = 0 To b Step 1 
     ... 
    Next 

Next 

这种情况的解决方法是简单的;创建一个变量,用于保存已删除的项目数量,然后在If -statement中检查i是否大于或等于当前项目数量减去已删除的项目数量。如果是这样,退出循环。

Dim ItemsRemoved As Integer = 0 
For i As Integer = 0 To ListBox1.Items.Count - 1 Step 1 
    If i >= ListBox1.Items.Count - ItemsRemoved Then Exit For 

    For j As Integer = 0 To ListBox2.Items.Count - 1 Step 1 
     If ListBox1.Items(i).ToString().Equals(ListBox2.Items(j).ToString()) = True Then 
      ListBox1.Items.RemoveAt(i) 
     End If 
    Next 
Next 

以供将来参考,你也应该随时删除/注释掉Try/Catch语句来,所以你可以看到其中错误发生,并获得更多的细节。

0

我的答案是,当你迭代任何集合时,你不应该尝试修改这个集合。在for-loops你遇到这样的麻烦。但是你可以使用迭代与while-loop没有问题

Try 
    Dim index As Integer = 0 
    While index < ListBox1.Items.Count '!! this code based on fact that ListBox1 item Count changes 
     For j As Integer = 0 To ListBox2.Items.Count - 1 ' <- this is ok because ListBox2 doesn't chage 
      If string.Equals(ListBox1.Items(index).ToString(), ListBox2.Items(j).ToString()) Then 
       ListBox1.Items.RemoveAt(index) 
       Continue While ' no index increase here because if you remove item N, next item become item N 
      End If 
     Next 
     index += 1 
    End While 
Catch ex As Exception 
    MsgBox("LOAD ERROR: " + ex.Message, vbCritical, "ERROR") 
End Try 

这是事情是如何工作的好例子。它显示了很少的技术

相关问题