C# DataGridView 红色 X

C# DataGridView Red X

我从网络服务器收到一个 JSON 文件,然后我用它来更新 C# DataGridView 控件的数据源 属性,但有时我的 DataGridView 消失并被一个大的,红色 'X'。这是我得到的 .NET 调用堆栈:

System.NullReferenceException: Object reference not set to an instance of an object.

System.Windows.Forms.DataGridViewTextBoxCell.PaintPrivate(Graphics graphics, Rectangle clipBounds, Rectangle cellBounds, Int32 rowIndex, DataGridViewElementStates cellState, Object formattedValue, String errorText, DataGridViewCellStyle cellStyle, DataGridViewAdvancedBorderStyle advancedBorderStyle, DataGridViewPaintParts paintParts, Boolean computeContentBounds, Boolean computeErrorIconBounds, Boolean paint)
System.Windows.Forms.DataGridViewTextBoxCell.Paint(Graphics graphics, Rectangle clipBounds, Rectangle cellBounds, Int32 rowIndex, DataGridViewElementStates cellState, Object value, Object formattedValue, String errorText, DataGridViewCellStyle cellStyle, DataGridViewAdvancedBorderStyle advancedBorderStyle, DataGridViewPaintParts paintParts)
System.Windows.Forms.DataGridViewCell.PaintWork(Graphics graphics, Rectangle clipBounds, Rectangle cellBounds, Int32 rowIndex, DataGridViewElementStates cellState, DataGridViewCellStyle cellStyle, DataGridViewAdvancedBorderStyle advancedBorderStyle, DataGridViewPaintParts paintParts)
System.Windows.Forms.DataGridViewRow.PaintCells(Graphics graphics, Rectangle clipBounds, Rectangle rowBounds, Int32 rowIndex, DataGridViewElementStates rowState, Boolean isFirstDisplayedRow, Boolean isLastVisibleRow, DataGridViewPaintParts paintParts)
System.Windows.Forms.DataGridViewRow.Paint(Graphics graphics, Rectangle clipBounds, Rectangle rowBounds, Int32 rowIndex, DataGridViewElementStates rowState, Boolean isFirstDisplayedRow, Boolean isLastVisibleRow)
System.Windows.Forms.DataGridView.PaintRows(Graphics g, Rectangle boundingRect, Rectangle clipRect, Boolean singleHorizontalBorderAdded)
System.Windows.Forms.DataGridView.PaintGrid(Graphics g, Rectangle gridBounds, Rectangle clipRect, Boolean singleVerticalBorderAdded, Boolean singleHorizontalBorderAdded)
System.Windows.Forms.DataGridView.OnPaint(PaintEventArgs e)
System.Windows.Forms.Control.PaintWithErrorHandling(PaintEventArgs e, Int16 layer)
System.Windows.Forms.Control.WmPaint(Message& m)
System.Windows.Forms.Control.WndProc(Message& m)
System.Windows.Forms.DataGridView.WndProc(Message& m)
System.Windows.Forms.NativeWindow.Callback(IntPtr hWnd, Int32 msg, IntPtr wparam, IntPtr lparam)

我该怎么做才能避免这个问题?

由于您的堆栈跟踪看起来与我的非常相似,我假设您遇到的问题与我遇到的问题类似。如果是这样,扩展 DataGridView 应该可以解决您的问题。

在您的项目中创建一个新的用户控件(我将我的命名为 DataGridViewExt,因此我将在此处使用该名称),如下所示:

public partial class DataGridViewExt : DataGridView
{
    public DataGridViewExt()
    {
        InitializeComponent();
    }

    protected override void OnPaint(PaintEventArgs e)
    {
        try
        {
            base.OnPaint(e);
        }
        catch (Exception)
        {
            this.Invalidate();
        }
    }
}

请注意,您扩展的是 DataGridView 而不是 UserControl。您在这里所做的只是在控件本身中添加一个额外的错误检查层,并告诉 DGV 在 运行 出现错误时重新绘制自身。在此之后,为您的项目添加此控件而不是每个 DataGridView(如果您已经添加了它们,请将每个 DataGridView 替换为您的 DataGridViewExt 或您决定在设计器中调用它的任何内容).

您可能 运行 在 DataGridViewExt Designer 中添加了对 AutoScaleMode 的处理,而 DataGridView 没有。删除这一行,你就可以开始了,不再有大红 X。