zoukankan      html  css  js  c++  java
  • 在DataGridView中的CellEndEdit事件中删除当前行报错

    写在前面,老婆问我一个UI的问题。我开始以为很简单,后来弄了一下,发觉挺难。找了不少资料才解决。在这个过程中学到不少东西,记录下来,以便以后复习。

    症状

    ===========

    在DataGridView中的CellEndEdit事件中删除当前行报错,信息如下:

    Operation is not valid because it results in a reentrant call to the SetCurrentCellAddressCore function

    分析

    ===========

    想要在一个控件的事件中删除掉控件本身,这个恐怕就是问题的根本原因了。我的第一感觉还是挺准的,可惜技术基础不扎实,没能贯彻下去。我最开始想:如果在这个事件处理函数中做不到,那老子再起一个线程,活生生等你这个事件执行结束了之后,再回来把你干掉总可以了吧。谁知又遇到了非创建控件的线程访问控件报exception的问题。

    已经是半夜十二点多了,头已经有点昏了。没关系,脑子不好使,有google。

    找到了如下的经典解决方案。

    //事件处理函数
    //不直接删掉该行,而是将要删掉的行存入数组,待另起的线程处理
    private void m_dataGridView_CellEndEdit(object sender, DataGridViewCellEventArgs e)
    {
        PushDelIndex(e.RowIndex);
        Thread delTh = new Thread(new ThreadStart(delRowThread));
        delTh.Start();
    }
    
    
    private int[] delIndex = null;//待删行号的数组
    private bool delFlag = true;//是否要不间断尝试删除数组中的行
    private bool deling = false;//是否有线程正在执行删除操作的锁变量
    
    private void PushDelIndex(int _index)
    {
        if(delIndex==null)
        {
            delIndex=new int[]{_index};
        }
        else
        {
            Array.Resize(ref delIndex,delIndex.Length+1);//展示如何扩充数组
            delIndex[delIndex.Length - 1] = _index;
        }
    }
    
    void delRowThread()
    {
        while (delFlag)
        {
            if (delIndex != null)
            {
                if (deling == false)
                {
                    delRow();
                }
            }
            Thread.Sleep(100);
        }
    }
    
    //此处展现了如何在非创建控件的线程里去修改控件的方法
    private delegate void delRowCallBack();
    void delRow()
    {
        if (PlayList.InvokeRequired)
        {
            deling = true;
            delRowCallBack o = new delRowCallBack(delRow);
            this.Invoke(o);
        }
        else
        {
            for (int i = 0; i < delIndex.Length; i++)
            {
                PlayList.Rows.RemoveAt(delIndex[i]);
            }
            deling = false;
            delIndex = null;
        }
    }
    }
  • 相关阅读:
    [NOIP2013] 提高组 洛谷P1979 华容道
    Vijos P1404 遭遇战
    CodeVS 1506 传话
    P1546 最短网络 Agri-Net
    HDU 4747 Mex
    POJ1020 Anniversary Cake
    【数据结构】平衡二叉树
    【数据结构】二叉排序树
    【数据结构】二叉树
    概念源于生活
  • 原文地址:https://www.cnblogs.com/awpatp/p/1592686.html
Copyright © 2011-2022 走看看