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

How can I remove more than one item from a listbox?

真的很烦人;或者,老实说,前一段时间它变得很烦人。

以编程方式从列表框中删除项目应该非常简单,但似乎我尝试的所有操作都以相同的方式结束:有一个例外。这次是"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()

我通过查询 table 填充列表框,并用查询结果填充字符串列表。然后我将该字符串列表指定为列表框的数据源。填充工作正常;是人口减少让我迷恋。

这是代码。对于这个问题,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() 中抛出异常,但我不明白为什么会出现问题。

如果发送三个 table 会发生什么:

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

是的,seems/should很简单。然而它只会与第一个合作,然后因该异常而崩溃。如果我不使用数据绑定——只是在填充列表框时手动逐一添加值,它会不会变得不那么胡思乱想?

更新

是的,将要删除的项目保存在列表中,然后在实际工作后一次将它们全部删除。我将代码更改为:

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);
        }
    }
    . . .

...现在工作正常。

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

您正试图在您同时更新的数据绑定控件上使用枚举器。它不会真的为此高兴。完成循环后,保存要对数据绑定控件所做的所有更改,然后尝试对已保存的每个更改尝试更新 gui 方法。