繁体   English   中英

DataGridView的GetCachedPen函数中的NullReferenceException

[英]NullReferenceException in GetCachedPen function of DataGridView

我们在WinForms的DataGridView中有一个NullReferenceException。 实际上我们正在使用DotNetBar中的DataGridViewX组件,但是这是一个围绕标准DataGridView的相当简单的包装器,所以我有理由相信它不对这个问题负责。 堆栈跟踪是:

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)

我在任何网站上都找不到任何类似错误的帖子。

我在.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

我可以看到这可能崩溃的唯一方法是,如果传入的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.");
    }
}

DGV的BorderStyle设置为BorderStyle.FixedSingle,因此传递给GetCachedPen的颜色参数应该是SystemColors.ControlText,对我来说应该永远不会为null?

我发现了一些与绘画有关的看似“随机”崩溃的帖子,但似乎都没有解决方案,也没有与GetCachedPen函数有关。 看看我们的错误记录数据库,我们可以看到,自从我们开始要求我们的用户提交崩溃日志以来,这已经在过去几年中使我们的软件崩溃了3次,所以它肯定不是系统性我们做错了,因为这是一个很好用的部分的软件。

有没有人见过这种崩溃,或类似的东西? 有针对这个的解决方法吗? 或者在WinForms控件中有这些绘制错误的某种解决方法吗?

我也有同样的问题。 但非常奇怪的是我只在我的笔记本电脑(Windows 10)上,在我的工作站(Windows 7)上收到它我没有这个问题。 在我的笔记本电脑上,我始终收到错误。 一个表单是开放的编辑,我做一些编辑,点击保存,然后我关闭表单,我总是收到以下错误:

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)

我不知道为什么只在某些计算机上发生这种情况,但我解决了以下问题。 在我的情况下,datagrid也包含在我自己的usercontrol中。 在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