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

…衆ロ難τιáo~ 提交于 2019-12-12 03:25:40

问题


This is really getting annoying; or, to be honest, it became quite annoying a good while back.

Programmatically removing items from a listbox should be pretty straightforward, yet it seems everything I try ends up the same: with an exception. This time it's "InvalidOperationException". In context (excerpt of log file):

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()

I populate the listbox by querying a table, and populating a list of string with the query results. I then assign that list of string as the data source of the listbox. The populating works fine; it's the de-populating that is giving me the fantods.

Here's the code. The key thing that SendDeliveries() calls, as to this problem, is 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));
    }
}

Even when there are multiple items in the listbox, only one is removed, because it crashes with the InvalidOperationException. The log file indicates the exception is thrown in SendDeliveries(), but I don't grok why there's a problem.

What should happen if there are three tables being sent is:

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

Yes, it seems/should be simple. Yet it will only cooperate with the first one, and then crash with that exception. Would it be less cranky if I didn't use data binding - just added the values manually, one-by-one, when populating the listbox?

UPDATE

Yes, holding the items to be removed in a list, and then removing them all at once after the fact works. I changed the code to this:

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

...and it works fine now.


回答1:


Not entirely sure, but I would try creating a list of the items you want to update in the GUI outside of your loop and then update the GUI with the list of items you then want to modify.

You are trying to use an enumerator on a data bound control you are updating at the same time. It won't be really happy about that. Save all of the changes you want to make to the data bound control after you complete the loop and then try update gui method on each of those changes you have saved.



来源:https://stackoverflow.com/questions/28490594/how-can-i-remove-more-than-one-item-from-a-listbox

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!