我有一个WPF触发(TextChanged)函数,该函数调用另外两个函数,当满足某些条件时,其子例程从DataGrid对象中删除行。
我有一种感觉,我可能会在删除多行时遇到竞争条件。当我在两个函数之间放置MessageBox.Show("somethings');
时,DataGrid中的2行将按预期删除,并在删除操作之间弹出消息框。
deleteFunction("item1");
MessageBox.Show("something");
deleteFunction("item2");
但是,如果仅删除MessageBox,则第一个函数会从DataGrid中删除单个行(item1)。
deleteFunction("item1");
deleteFunction("item2");
我已经尝试了各种方法来解决这个问题,Thread.Sleep(500)在函数调用之间,设置队列以FIFO请求,线程锁定。异步......似乎没有什么对我有用。
我甚至不确定它实际上是一个竞争条件问题。我开始想知道在调用MessageBox时是否有一些与DataGrid对象的Thread连接,并释放了另一个与之交互的函数的控件。
以下代码:
private void streamCode_TextChanged(object sender, TextChangedEventArgs e)
{
if (configurationSectionLoaded == true)
{
streamCodeAlphanumeric(streamCode.Text);
streamCodeIsChar128(streamCode.Text);
}
formEdited = true;
}
private bool streamCodeAlphanumeric(string value)
{
dataValidation dv = new dataValidation();
if (dv.isAlphanumeric(value))
{
streamCode.Background = Brushes.LightGreen;
editStreamcode.Background = Brushes.LightGreen;
editStreamcode.IsEnabled = true;
//MessageBox.Show("scE01 Deleting");
//q.Enqueue(new UILogDeleteQueue() { qEntryType = "scE01" });
try
{
UILogRemoveRow("scE01");
}
catch(Exception e)
{
MessageBox.Show(e.ToString());
}
return true;
}
else
{
editStreamcode.IsEnabled = false;
streamCode.Background = Brushes.LightPink;
UILogAddRow("scE01", "Stream Code", "Non-Alphanumeric Characters Detected!");
return false;
}
}
private bool streamCodeIsChar128(string value)
{
dataValidation dva = new dataValidation();
if (dva.isChar128(value))
{
streamCode.Background = Brushes.LightGreen;
editStreamcode.Background = Brushes.LightGreen;
editStreamcode.IsEnabled = true;
//MessageBox.Show("scE02 Deleting");
try
{
UILogRemoveRow("scE02");
}
catch (Exception e)
{
MessageBox.Show(e.ToString());
}
return true;
}
else
{
editStreamcode.IsEnabled = false;
streamCode.Background = Brushes.LightPink;
UILogAddRow("scE02", "Stream Code", "Invalid Length Detected!");
return false;
}
}
最后这里是删除行代码:
private void UILogRemoveRow(string entryCode)
{
int rowCount;
rowCount = UILog.Items.Count;
if (rowCount > 0)
{
for (int i = 0; i < rowCount; i++)
{
DataGridRow row = (DataGridRow)UILog.ItemContainerGenerator.ContainerFromIndex(i);
var selectedItem = UILog.ItemContainerGenerator.ContainerFromIndex(i);
if (row != null)
{
UILogObject theItem = (UILogObject)row.DataContext;
if (theItem.entryType == entryCode)
{
UILog.Items.RemoveAt(i);
}
}
}
}
}
非常感谢任何协助。
更新:包含UILogAddRow
功能
private void UILogAddRow(string entryCode, string entryIdentifier, string entryDetail)
{
bool itemExists = false;
int rowCount;
rowCount = UILog.Items.Count;
if (rowCount > 0)
{
for (int i = 0; i < rowCount; i++)
{
DataGridRow row = (DataGridRow)UILog.ItemContainerGenerator.ContainerFromIndex(i);
if (row != null)
{
UILogObject theItem = (UILogObject)row.DataContext;
if (theItem.entryType == entryCode)
{
itemExists = true;
}
}
}
}
else
{
//MessageBox.Show(rowCount.ToString());
}
if (itemExists != true)
{
UILog.Items.Add(new UILogObject() { entryType = entryCode, identifier = entryIdentifier, detail = entryDetail });
}
UILog.Items.Refresh();
}
答案 0 :(得分:1)
而不是使用低级容器元素(DataGridRow),将项目转换为您的已知类型,然后搜索并删除
private void UILogRemoveRow(string entryCode)
{
var item = UILog.Items.OfType<UILogObject>()
.FirstOrDefault(x => x.entryType == entryCode);
if (item != null)
UILog.Items.Remove(item);
}