Skip to content

Commit aeb1e35

Browse files
[release/9.0] Add a null-check for "DataGridView" property before executing OnMouseUp in function OnMouseUpInternal (#12742)
Backport of #12701 to release/9.0 Customer Impact Application crashes when the customer clicks on a DataGridView cell, where previously the content was selected. Root Cause This issue is caused by PR Enable nullability in remaining DataGridViewCell members #10406. which removed the check whether the parent control is null before executing OnMouseUp when handling a MouseUp event. That fix moved the null check to the top of our MouseUp event handler. However, reference to the parent control can be set to null when this cell (or a row containing it) is cleared in the user-provided click event handler which is invoked in the middle of this method. We should restore the null check before accessing the parent DataGridView.
1 parent ecc65f0 commit aeb1e35

File tree

2 files changed

+32
-4
lines changed

2 files changed

+32
-4
lines changed

src/System.Windows.Forms/src/System/Windows/Forms/Controls/DataGridView/DataGridViewCell.cs

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3075,7 +3075,9 @@ internal void OnMouseUpInternal(DataGridViewCellMouseEventArgs e)
30753075
DataGridView.OnCommonCellContentClick(e.ColumnIndex, e.RowIndex, e.Clicks > 1);
30763076
}
30773077

3078-
if (e.ColumnIndex < DataGridView.Columns.Count && e.RowIndex < DataGridView.Rows.Count)
3078+
// Verify that the DataGridView is not null again, because a custom
3079+
// Click event handler may delete the cell and the reference to parent DataGridView.
3080+
if (DataGridView is not null && e.ColumnIndex < DataGridView.Columns.Count && e.RowIndex < DataGridView.Rows.Count)
30793081
{
30803082
OnMouseUp(e);
30813083
}
@@ -3795,16 +3797,16 @@ public virtual void PositionEditingControl(
37953797
isFirstDisplayedColumn,
37963798
isFirstDisplayedRow);
37973799

3798-
if (DataGridView?.EditingControl is not null)
3800+
if (DataGridView?.EditingControl is { } editingControl)
37993801
{
38003802
if (setLocation)
38013803
{
3802-
DataGridView.EditingControl.Location = new Point(editingControlBounds.X, editingControlBounds.Y);
3804+
editingControl.Location = new Point(editingControlBounds.X, editingControlBounds.Y);
38033805
}
38043806

38053807
if (setSize)
38063808
{
3807-
DataGridView.EditingControl.Size = new Size(editingControlBounds.Width, editingControlBounds.Height);
3809+
editingControl.Size = new Size(editingControlBounds.Width, editingControlBounds.Height);
38083810
}
38093811
}
38103812
}

src/System.Windows.Forms/tests/UnitTests/System/Windows/Forms/DataGridViewCellTests.cs

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6603,6 +6603,32 @@ public void DataGridViewCell_OnContentClick_InvokeInternalRaiseAutomationNotific
66036603
Times.Exactly(2));
66046604
}
66056605

6606+
// Regression test for https://github.com/dotnet/winforms/issues/12692
6607+
[WinFormsFact]
6608+
public void DataGridViewCell_OnContentClick_ClearAndReAddCell_InvokeOnMouseUpInternal()
6609+
{
6610+
using SubDataGridViewCheckBoxCell cellTemplate = new();
6611+
using DataGridViewColumn column = new()
6612+
{
6613+
CellTemplate = cellTemplate
6614+
};
6615+
6616+
using DataGridView dataGridView = new();
6617+
dataGridView.Columns.Add(column);
6618+
var cell = (SubDataGridViewCheckBoxCell)dataGridView.Rows[0].Cells[0];
6619+
6620+
dataGridView.CellContentClick += new DataGridViewCellEventHandler((s, e) =>
6621+
{
6622+
DataGridView dataGridView = (DataGridView)s;
6623+
dataGridView.Rows.Clear();
6624+
dataGridView.Rows.Add();
6625+
});
6626+
// Set cell value to ensure it is properly formatted.
6627+
cell.Value = false;
6628+
Action act = () => cell.MouseClick(new DataGridViewCellMouseEventArgs(0, 0, 10, 10, new MouseEventArgs(MouseButtons.Left, 1, 10, 10, 0)));
6629+
act.Should().NotThrow();
6630+
}
6631+
66066632
private class SubDataGridViewCheckBoxCell : DataGridViewCheckBoxCell
66076633
{
66086634
public SubDataGridViewCheckBoxCell()

0 commit comments

Comments
 (0)