为什么此列表框项目删除代码失败?

时间:2014-11-06 00:42:45

标签: c# listbox compact-framework windows-ce listboxitems

我在Windows CE应用中获得了此代码:

for (int i = listBoxWork.Items.Count - 1; i > -1; i--)
{
    if (listBoxWork.Items[i].ToString().IndexOf(listboxVal) != -1)
    {
        listBoxWork.Items.RemoveAt(i);
    }
}

在System.Collections.ArrayList.ArrayListEnumeratorSimple.MoveNext()... "

中," 无效操作异常崩溃

我在"常规"中尝试相同的确切代码Windows表单应用程序,它完美地运行。如果这是Windows CE无法以这种方式处理的事情,那么可以我如何从列表框中删除项目?

更新

这是" VS 2013代码" (目标框架== .NET Framework 4.5.1,平台目标==任何CPU)有效(列表框中的" blaINV"项目已删除):

private void button44_Click(object sender, EventArgs e)
{
    String listboxVal = "blaINV";
    for (int i = listboxWork.Items.Count - 1; i >= 0; --i)
    {
        if (listboxWork.Items[i].ToString().IndexOf(listboxVal) != -1)
        {
            listboxWork.Items.RemoveAt(i);
        }
    }
}

该表单上的using语句(这是一个" sandbox"表单,我测试了各种各样的东西):

using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Data.OleDb;
using System.DirectoryServices.AccountManagement;
using System.Drawing;
using System.IO;
using System.Linq;
using System.Net;
using System.Text;
using System.Text.RegularExpressions;
using System.Threading.Tasks;
using System.Windows.Forms;
using System.Xml;

" VS 2008"代码如下。

首先请注意,该项目的Target框架应该是.NET 3.5,但是"目标框架:"在Project>中显示为灰色属性>应用标签;如果我选择项目>更改目标平台,"当前平台:" == Windows CE)

但是如果我去Project>属性>构建选项卡,配置设置为"活动(调试)",平台设置为"活动(任何CPU)",并且平台目标设置为"任何CPU& #34;并且是下拉列表中的唯一选项。

在“设备”选项卡(项目>属性>设备)上,目标设备设置为" Pocket PC 2003 SE Emulator"但我并没有真正使用它。当我需要测试时,我只是将.exe复制到手持设备。

无论如何,这里是代码(失败):

private void UpdateGUIAfterTableSend(String listboxVal)
{
    for (int i = listBoxWork.Items.Count - 1; i >= 0; --i)
    {
        if (listBoxWork.Items[i].ToString().IndexOf(listboxVal) != -1)
        {
            listBoxWork.Items.RemoveAt(i);
        }
    }
}

正如你所看到的,除了a"虚假"要搜索的字符串在工作代码中提供。实际的列表框包含一个匹配" listboxVal&#34 ;;的值。然而,不仅没有删除,如上所述的例外情况也会发生。

以下是非工作表单中唯一的使用声明:

using System;
using System.Windows.Forms;

namespace HHS
{
    using System.Collections.Generic; // R# put this "using" here; like Don Henley in "The Last Resort," I don't know why

更新2

我将命名空间后的命令移动到命名空间之上只是为了看看它是否会产生任何不同。它没有。

更新3

我在代码中添加了一个catch块:

try
{
    for (int i = listBoxWork.Items.Count - 1; i >= 0; --i)
    {
        if (listBoxWork.Items[i].ToString().IndexOf(listboxVal) != -1)
        {
            listBoxWork.Items.RemoveAt(i);
        }
    }
}
catch (Exception ex)
{
    MessageBox.Show(String.Format(
        "Exception in UpdateGUIAfterTableSend(). Message == {0}; InEx == {1}; StackTrace == {2}", 
            ex.Message, ex.InnerException, ex.StackTrace));
}

...但我没有看到消息框 - 之前的异常显示,并且在解雇时,应用程序崩溃 - 即使是薄金属" bing"我之前从未听过的声音。

更新4

好的,为了尝试深入了解,我将MessageBox.Show()的精彩内容写入代码:

private void UpdateGUIAfterTableSend(String listboxVal)
{
    try
    {
        MessageBox.Show("Made it before for loop in UpdateGUIAfterTableSend()");
        for (int i = listBoxWork.Items.Count - 1; i >= 0; --i)
        {
            MessageBox.Show("Made it before if condition in UpdateGUIAfterTableSend()");
            if (listBoxWork.Items[i].ToString().IndexOf(listboxVal) != -1)
            {
                MessageBox.Show("Made it before remove line in UpdateGUIAfterTableSend()");
                listBoxWork.Items.RemoveAt(i);
            }
        }
        MessageBox.Show("Made it before listBoxMessages.Items.Add() in     
          UpdateGUIAfterTableSend()");
        listBoxMessages.Items.Add(String.Format("{0} sent at {1}", listboxVal, 
          DateTime.Now.ToLongTimeString()));
        MessageBox.Show("Made it after listBoxMessages.Items.Add() in 
           UpdateGUIAfterTableSend()");
    }
    catch (Exception ex)
    {
        MessageBox.Show(String.Format(
            "Exception in UpdateGUIAfterTableSend(). Message == {0}; InEx == {1}; StackTrace 
               == {2}", ex.Message, ex.InnerException, ex.StackTrace));
    }
}

这就是这样称呼的:

private void menuItemSEND_Inventories_Click(object sender, EventArgs e)
{
    SendInventories();
}

private void SendInventories()
{
    Cursor curse = Cursor.Current;
    Cursor.Current = Cursors.WaitCursor;
    try
    {
        foreach (String tblname in listBoxWork.Items)
        {
            // Ignore DSD tables
            if (tblname.IndexOf("DSD") == 0) continue;
            int siteNum = HHSDBUtils.GetSiteNumForTableName(tblname);
            String fileName = HHSUtils.GetGeneratedINVFileName(siteNum);
            String xmlData = HHSDBUtils.SaveAndGetINVDataAsXMLFromTable(tblname, fileName);
            String uri = 
                String.Format("http:100.200.400.800:1500/api/inventory/sendXML/duckbill/platypus/{0}", fileName);
            RESTUtils.SendHTTPRequestNoCredentials(uri, RESTUtils.HttpMethods.POST, xmlData, 
               "application/xml");
            HHSDBUtils.DeleteTableReference(tblname, "INV");
            HHSDBUtils.DropSQLiteTable(tblname, siteNum);
            UpdateGUIAfterTableSend(tblname);
        }
    }
    finally
    {
        Cursor.Current = curse;
    }
}

所以你可以看到,在调用UpdateGUIAfterTableSend()之后没有任何反应。这是我在选择发送>之前看到的。库存和引发这一系列事件:

enter image description here

...这就是我在崩溃之前看到的(listboxitem删除代码实际 正在工作,我现在可以看到):

enter image description here

在驳回最后一次"使它成为" MessageBox.Show(),它如前所述崩溃。为什么?!?!?之后没有别的事情发生了!?!

更新5

所以我在方法(SendInventories())中添加了一个catch块,它实际上似乎是罪魁祸首:

catch (Exception ex)
{
    MessageBox.Show(String.Format(
        "Exception in SendInventories(); Message == {0}, InEx == {1}, StackTrace == {2}", 
            ex.Message, ex.InnerException, ex.StackTrace));
}  

......我看到了这个:

enter image description here

然而,通过以这种方式捕获异常,应用程序不会崩溃。它似乎无害 - 我想要完成的事情已经完成。所以,虽然对这个例外的细节一点肯定(没有双关语意图),但也许我现在只是压制/吞下它...

更新6

所以,如果我将catch块更改为:

catch (Exception ex)
{
    if (!ex.Message.Contains("InvalidOperationException"))
    {
        MessageBox.Show(String.Format(
            "Exception in SendInventories(); Message == {0}, InEx == {1}, StackTrace == {2}",
                ex.Message, ex.InnerException, ex.StackTrace));
    }
}            

...它工作得很好(我看到没有例外,两个列表框都按预期更新)。我想我只是把它归结为古怪的Windows CE世界的变幻莫测。

1 个答案:

答案 0 :(得分:2)

此代码失败,因为for循环已将列表框中的总项目保存为10 然后,你是邪恶的,通过采取一个项目,让列表框继续循环直到10,而实际上,你的列表框项目只计数9(你刚刚删除了一个项目)。

一种方法是使用:

  
    

if(listBoxWork.Items.Contains(listboxVal)
       {
       获得指数;
       从listBoxWork中删除它;
       }

  


更新
在for循环中,您可以在删除项目后设置index = index - 1。
Visual Studio 2008仍然是原始的,你不能指望它像VS 2013一样。

干杯,