删除多行时,某些行仍保留在DataGrid中

时间:2018-01-19 13:57:04

标签: c# wpf datagrid

我有一个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();
}

1 个答案:

答案 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);
}