DataGridView InvalidOperationException可重入调用SetCurrentCellAddressCore

时间:2017-06-09 11:18:25

标签: c# datagridview

我已经为此工作了大约8个月。直到最近我从DataSet / DataTables转移到列表时,这一直是一件令人烦恼的事情。现在这个问题更加普遍(我认为因为列表看起来效率更高)。

这个问题已被问过几次,但没有一个真正触及真正发生的事情(也没有任何答案)。奇怪的是我无法隔离我的代码中的哪个位置导致异常,因为调试器会启动只有这段代码的program.cs:

    [STAThread]
    static void Main()
    {
        Application.EnableVisualStyles();
        Application.SetCompatibleTextRenderingDefault(false);
        Application.Run(new MyApp());

    }

应用程序异常位于Application.Run ...行。

我使用DataGridView作为后台处理日志显示。我在服务中有许多后台进程,可以与winform应用程序进行通信。表单侦听这些消息(事件处理程序/信号器)并删除消息(如FIFO队列)不超过列表中的最大定义量然后处理消息并将它们排序到BindingList []。然后在datagrid中,如果我点击一个项目,它将在文本框中显示完整的消息。我关闭了multiselect,datagridview是只读的。

哦,BindingList []从另一个控件绑定/反弹到datagrid,这样我就可以选择在datagridview中显示哪个列表。这不是问题,因为我通过在代码中强制使用单个特定列表来解决问题并且仍然存在问题。

为了让它崩溃,我可以多次点击datagrid,最终会崩溃。如果我真的想快速崩溃,我点击datagridview并向下和向上滚动(键盘箭头),我可以在几秒钟内崩溃。

我在StackOverflow上找到了this article (click here)来描述正在发生的事情。在其中一条评论中,它指的是Microsoft Bug Report(click here)这是设计的统计数据!然而,大多数人都在谈论操纵我没有做的细胞。最重要的消息几乎与我发生的一样,但程序员正在使用继承的DataGridView,因此他的解决方案对我不起作用。

这与添加和/或删除BindingList中的项目有关。如果在DataGridView中滚动/选择时有任何一个进行,我可以让它崩溃。但是这段代码非常简单:

    private void DelRow( string szTableName)
    {
        try
        {
            int nProcQueue = qdList.Queue(szTableName);
            MsgQueues[nProcQueue].RemoveAt(0);

            this.BeginInvoke(new MethodInvoker(Refresh_dgvDetail));
        }
        catch (Exception ex) 
        {
            LogEx(ex); 
        }
    }

    private void AddRow(LogObject oLogObject, string szTableName)
    {
        try
        {
            int nQueueNumber = qdList.Queue(szTableName); // helper object to return queue number based off the name of the list

            MsgQueues[nQueueNumber].Add(oLogObject);


            this.BeginInvoke(new MethodInvoker(Refresh_dgvDetail));
        }
        catch (Exception ex) 
        { 
           LogEx(ex);
        }
    }

这真的好像是一个c#bug ...为什么MS会按照我的设计来实现这个......?

任何人都知道如何阻止这种行为?

2 个答案:

答案 0 :(得分:1)

Grek40,你是对的;我错了。我只为添加做了MethodInvoker;不是删除。必须为两者做好准备。基本上任何触及datagridview的方法都需要MethodInvoker。这是我所做的一个例子:

this.Invoke((MethodInvoker)委托{MsgQueues [nCurrentQueue] .RemoveAt(0);});

问题消失了。

答案 1 :(得分:0)

将侧面的列设置为ReadOnly = true;