Как я могу удалить более одного элемента из списка?
Это действительно становится раздражающим; или, если честно, это стало довольно раздражающим некоторое время назад.
Удаление элементов из списка программным способом должно быть довольно простым, но, похоже, все, что я пытаюсь сделать, заканчивается одинаково: за исключением. На этот раз это "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 ответ
Не совсем уверен, но я бы попытался создать список элементов, которые вы хотите обновить в GUI за пределами вашего цикла, а затем обновить GUI со списком элементов, которые вы затем хотите изменить.
Вы пытаетесь использовать перечислитель для элемента управления с привязкой к данным, который вы обновляете одновременно. Это не будет очень рад этому. Сохраните все изменения, которые вы хотите внести, в элемент управления с привязкой к данным после завершения цикла, а затем попробуйте обновить метод gui для каждого из сохраненных изменений.