如何从列表框中删除多个项目?

时间:2015-02-13 00:38:27

标签: c# listbox datasource windows-ce invalidoperationexception

真的变得烦人;或者,说实话,它回来后变得很烦人。

以编程方式从列表框中删除项目应该非常简单,但似乎我尝试的所有内容都是相同的:有一个例外。这一次它是" InvalidOperationException"。在上下文中(日志文件的摘录):

Date: 2/12/2015 7:15:17 PM
Message: Reached frmMain.UpdateGUIAfterTableSend

Date: 2/12/2015 7:15:17 PM
Message: From frmMain.SendDeliveries(): InvalidOperationException; Inner Ex: ; Stack Trace:    at System.Collections.ArrayList.ArrayListEnumeratorSimple.MoveNext()
   at HHS.frmMain.SendDeliveries()

我通过查询表填充列表框,并使用查询结果填充字符串列表。然后我将该字符串列表指定为列表框的数据源。人口很好;它是让人兴奋的消遣。

这是代码。关于这个问题,SendDeliveries()调用的关键是UpdateGUIAfterTableSend()

private void SendDeliveries()
{
    ExceptionLoggingService .Instance.WriteLog("Reached
frmMain.SendDeliveries");
    Cursor curse = Cursor.Current;
    Cursor.Current = Cursors.WaitCursor;
    try
    {
        bool firstRecord = false;
        bool lastRecord = false;
        try
        {
            foreach (String tblname in listBoxWork.Items)
            {
                // Ignore INV tables
                if (tblname.IndexOf("INV") == 0) continue;
                String tblSiteNum =
hhsdbutils.GetSiteNumForTableName(tblname);
                String fileName =
HHSUtils.GetGeneratedDSDFileName(tblSiteNum);
                String xmlData =
hhsdbutils.GetDSDDataAsXMLFromTable(tblname, fileName);
                // Verify that "delivery" is the correct val in this URL
                String uri = String.Format(
                    "{0}delivery/sendXML/duckbill/platypus/{1}",
HHSConsts.BASE_REST_URL, fileName);
                fileXferImp = HHSConsts.GetFileTransferMethodology();
                fileXferImp.SendDataContentsAsXML(uri, xmlData, tblname,
siteNum, firstRecord, lastRecord);
                hhsdbutils.DeleteTableReference(tblname);
                hhsdbutils.DropTable(tblname, tblSiteNum);
                UpdateGUIAfterTableSend(tblname);
            }
        }
        catch (Exception ex)
        {
            String msgInnerExAndStackTrace = String.Format(
                                    "{0}; Inner Ex: {1}; Stack Trace:
{2}", ex.Message, ex.InnerException, ex.StackTrace);
           ExceptionLoggingService.Instance.WriteLog(String.Format("From
frmMain.SendDeliveries(): {0}", msgInnerExAndStackTrace));
        }
    }
    finally
    {
        Cursor.Current = curse;
    }
}

private void UpdateGUIAfterTableSend(String listboxVal)
{
    ExceptionLoggingService.Instance.WriteLog("Reached
frmMain.UpdateGUIAfterTableSend");
    try
    {
        BindingSource bs = listBoxWork.DataSource as BindingSource;
        List<string> values = bs.DataSource as List<string>;
        values.RemoveAll(v => v.Contains(listboxVal));
        bs.ResetBindings(false);
    }
    catch (Exception ex)
    {
        String msgInnerExAndStackTrace = String.Format("{0}; Inner Ex:
{1}; Stack Trace: {2}", ex.Message, ex.InnerException, ex.StackTrace);
        ExceptionLoggingService.Instance.WriteLog(String.Format("Fro
frmMain.UpdateGUIAfterTableSend: {0}", msgInnerExAndStackTrace));
    }
}

即使列表框中有多个项目,也只会删除一个项目,因为它会因InvalidOperationException崩溃。日志文件表明在SendDeliveries()中抛出异常,但我不知道为什么会出现问题。

如果有三个表被发送会发生什么:

Send the first one, and remove the listbox item that represents it to the user from the listbox
Send the second one, and remove the listbox item that represents it to the user from the listbox
Send the third one, and remove the listbox item that represents it to the user from the listbox

是的,似乎/应该很简单。然而,它只会与第一个合作,然后崩溃与该例外。如果我没有使用数据绑定,它会不那么胡思乱想 - 只需在填充列表框时手动逐个添加值吗?

更新

是的,在列表中保留要删除的项目,然后在事实发生后立即将其全部删除。我将代码更改为:

private void SendDeliveries()
{
    List<String> tableNames = new List<string>();
    try
    {
        try
        {
            foreach (String tblname in listBoxWork.Items)
            {
                String tblSiteNum 
    hhsdbutils.GetSiteNumForTableName(tblname);
                . . .
                tableNames.Add(tblname);
            }
            UpdateGUIAfterTableSend(tableNames);
        }
        . . .

private void UpdateGUIAfterTableSend(IEnumerable<String> listboxVals)
{
    try
    {
        BindingSource bs = listBoxWork.DataSource as BindingSource;
        if (bs != null)
        {
            List<string> values = bs.DataSource as List<string>;
            foreach (String listboxVal in listboxVals)
            {
                if (values != null)
                {
                    values.RemoveAll(v => v.Contains(listboxVal));
                }
            }
        }
        if (null != bs)
        {
            bs.ResetBindings(false);
        }
    }
    . . .

......现在工作正常。

1 个答案:

答案 0 :(得分:1)

不完全确定,但我会尝试在循环外的GUI中创建要更新的项目列表,然后使用您想要修改的项目列表更新GUI。

您正在尝试在要更新的数据绑定控件上使用枚举器。它对此并不高兴。完成循环后,将要对数据绑定控件进行的所有更改保存,然后对保存的每个更改尝试更新gui方法。