简体   繁体   English

DataGridView的GetCachedPen函数中的NullReferenceException

[英]NullReferenceException in GetCachedPen function of DataGridView

We are having a NullReferenceException in the DataGridView of WinForms. 我们在WinForms的DataGridView中有一个NullReferenceException。 Actually we are using the DataGridViewX component from DotNetBar however this is a fairly simple wrapper around the standard DataGridView so I have reason to believe it is not responsible for the issue. 实际上我们正在使用DotNetBar中的DataGridViewX组件,但是这是一个围绕标准DataGridView的相当简单的包装器,所以我有理由相信它不对这个问题负责。 The stack trace is: 堆栈跟踪是:

Unhandled thread exception System.NullReferenceException: Object reference not set to an instance of an object.
   at System.Windows.Forms.DataGridView.GetCachedPen(Color color)
   at System.Windows.Forms.DataGridView.PaintBorder(Graphics g, Rectangle clipRect, Rectangle bounds)
   at System.Windows.Forms.DataGridView.OnPaint(PaintEventArgs e)
   at DevComponents.DotNetBar.Controls.DataGridViewX.OnPaint(PaintEventArgs e)
   at System.Windows.Forms.Control.PaintWithErrorHandling(PaintEventArgs e, Int16 layer)
   at System.Windows.Forms.Control.WmPaint(Message& m)
   at System.Windows.Forms.Control.WndProc(Message& m)
   at System.Windows.Forms.DataGridView.WndProc(Message& m)
   at System.Windows.Forms.Control.ControlNativeWindow.OnMessage(Message& m)
   at System.Windows.Forms.Control.ControlNativeWindow.WndProc(Message& m)
   at System.Windows.Forms.NativeWindow.Callback(IntPtr hWnd, Int32 msg, IntPtr wparam, IntPtr lparam)

I cannot find any posts on any sites for a similar error. 我在任何网站上都找不到任何类似错误的帖子。

I reviewed the code for this function at the .NET Reference Source , and this (internal/Friend) function takes a Color and looks inside a private hash table of cached pens: 我在.NET Reference Source中查看了此函数的代码 ,这个(内部/朋友)函数接受一个Color并查看缓存笔的私有哈希表:

internal Pen GetCachedPen(Color color)
{
    Pen pen = (Pen) this.pens[color];
    if (pen == null)
    {
        pen = new Pen(color);
        this.pens.Add(color, pen);
    }
    return pen;
}

https://referencesource.microsoft.com/#System.Windows.Forms/winforms/Managed/System/WinForms/DataGridViewMethods.cs,205118801a8f1ca9 https://referencesource.microsoft.com/#System.Windows.Forms/winforms/Managed/System/WinForms/DataGridViewMethods.cs,205118801a8f1ca9

The only way I can see this possibly crashing is if the Color passed in is null, however the only time I can see this function get called is: 我可以看到这可能崩溃的唯一方法是,如果传入的Color为null,但是我唯一能看到此函数被调用的时间是:

if (paintingNeeded)
{
    if (this.BorderStyle == BorderStyle.Fixed3D)
    {
        if (Application.RenderWithVisualStyles)
        {
            Pen pen = GetCachedPen(VisualStyleInformation.TextControlBorder);
            g.DrawRectangle(pen, new Rectangle(0, 0, bounds.Width - 1, bounds.Height - 1));
        }
        else
        {
            ControlPaint.DrawBorder3D(g, bounds, Border3DStyle.Sunken);
        }
    }
    else if (this.BorderStyle == BorderStyle.FixedSingle)
    {
        Pen pen = GetCachedPen(SystemColors.ControlText);
        g.DrawRectangle(pen, new Rectangle(0, 0, bounds.Width - 1, bounds.Height - 1));
    }
    else
    {
        Debug.Fail("DataGridView.PaintBorder - Unexpected BorderStyle value.");
    }
}

The BorderStyle of the DGV is set to BorderStyle.FixedSingle, so the color parameter getting passed to GetCachedPen should be SystemColors.ControlText, which for me should never be null? DGV的BorderStyle设置为BorderStyle.FixedSingle,因此传递给GetCachedPen的颜色参数应该是SystemColors.ControlText,对我来说应该永远不会为null?

I have found some posts of seemingly "random" crashes from the DGV related to painting, but none seemed to have a solution and none were related to the GetCachedPen function. 我发现了一些与绘画有关的看似“随机”崩溃的帖子,但似乎都没有解决方案,也没有与GetCachedPen函数有关。 Looking at our error logging database we can see this has crashed our software 3 times in the last couple of years since we started asking our users to submit crash logs, so its certainly not something systematic we are doing wrong as this is a well used part of the software. 看看我们的错误记录数据库,我们可以看到,自从我们开始要求我们的用户提交崩溃日志以来,这已经在过去几年中使我们的软件崩溃了3次,所以它肯定不是系统性我们做错了,因为这是一个很好用的部分的软件。

Has anyone seen this crash before, or something similar? 有没有人见过这种崩溃,或类似的东西? Is there a solution to this? 有针对这个的解决方法吗? Alternatively is there some kind of workaround to these painting errors in a WinForms control? 或者在WinForms控件中有这些绘制错误的某种解决方法吗?

I have the same problem. 我也有同样的问题。 But very strange I receive it only on my laptop (Windows 10), on my workstation (Windows 7) I don't have this problem. 但非常奇怪的是我只在我的笔记本电脑(Windows 10)上,在我的工作站(Windows 7)上收到它我没有这个问题。 On my laptop I receive the error consistently. 在我的笔记本电脑上,我始终收到错误。 A form is openend for editing, I do some editing, click on Save, then I close the form and I always receive the following error: 一个表单是开放的编辑,我做一些编辑,点击保存,然后我关闭表单,我总是收到以下错误:

Unhandled Exception: System.NullReferenceException: Object reference not set to an instance of an object.
   at System.Windows.Forms.DataGridView.GetCachedPen(Color color)
   at System.Windows.Forms.DataGridView.PaintBorder(Graphics g, Rectangle clipRect, Rectangle bounds)
   at System.Windows.Forms.DataGridView.OnPaint(PaintEventArgs e)
   at System.Windows.Forms.Control.PaintWithErrorHandling(PaintEventArgs e, Int16 layer)
   at System.Windows.Forms.Control.WmPaint(Message& m)
   at System.Windows.Forms.Control.WndProc(Message& m)
   at System.Windows.Forms.DataGridView.WndProc(Message& m)
   at System.Windows.Forms.Control.ControlNativeWindow.OnMessage(Message& m)
   at System.Windows.Forms.Control.ControlNativeWindow.WndProc(Message& m)
   at System.Windows.Forms.NativeWindow.DebuggableCallback(IntPtr hWnd, Int32 msg, IntPtr wparam, IntPtr lparam)

I don't know why this is happening on only some computers but I fixed the problem as follows. 我不知道为什么只在某些计算机上发生这种情况,但我解决了以下问题。 The datagrid is in my case also wrapped in my own usercontrol. 在我的情况下,datagrid也包含在我自己的usercontrol中。 In the usercontrol you can override the OnPaint event. 在usercontrol中,您可以覆盖OnPaint事件。

Protected Overrides Sub OnPaint(ByVal e As System.Windows.Forms.PaintEventArgs)
    Try
        ' Dispose I will not do anything if done.
        If Not Me.IsDisposed Then
            MyBase.OnPaint(e)
        Else
            Debug.Print("SingleRecordDatagrid: Datagridview already disposed.")
        End If

    Catch ex As NullReferenceException
        ' Even if you give an exception, don't do anything.
        Debug.Print("SingleRecordDatagrid: " & ex.Message & "  StackTrace: " & vbCrLf & ex.StackTrace)
    End Try
End Sub

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM