簡體   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