.NET version
10.0.12
Did it work in .NET Framework?
Yes
Did it work in any of the earlier releases of .NET Core or .NET 5+?
No response
Issue description
Very easy to reproduce. Using following codes. Scroll down to the bottom. Select any row. It will take seconds to select a row.
private void Form1_Load(object sender, EventArgs e)
{
DataGridView Tester = new DataGridView();
Tester.Columns.Add("trest", "trstr");
for (int i = 0; i < 30000; i++)
{
Tester.Rows.Add($"Row {i:00000}");
}
Tester.Visible = true;
Tester.Dock = DockStyle.Fill;
this.Controls.Add(Tester);
}
The bug is in DataGridViewRowCollection. GetVisibleIndex repeats Count (30001) and DisplayIndexToRowIndex also repeats Count (30001).
internal int GetVisibleIndex(DataGridViewRow row)
{
for (int i = 0; i < Count; i++)
{
int index = DisplayIndexToRowIndex(i);
if (index != -1 && _items[index] == row)
{
return i;
}
}
return -1;
}
internal int DisplayIndexToRowIndex(int visibleRowIndex)
{
Debug.Assert(visibleRowIndex < GetRowCount(DataGridViewElementStates.Visible));
// go row by row
// the alternative would be to do a binary search using DataGridViewRowCollection::GetRowCount(...)
// but that method also iterates thru each row so we would not gain much
int indexOfCurrentVisibleRow = -1;
for (int i = 0; i < Count; i++)
{
if ((GetRowState(i) & DataGridViewElementStates.Visible) == DataGridViewElementStates.Visible)
{
indexOfCurrentVisibleRow++;
}
if (indexOfCurrentVisibleRow == visibleRowIndex)
{
return i;
}
}
Debug.Assert(false, "we should have found the row already");
return -1;
}
GetVisibleIndex is called by DataGridViewCellAccessibleObject:Name
Following codes bypass the performance issue.
private void Form1_Load(object sender, EventArgs e)
{
DataGridView Tester = new DataGridView();
Tester.Columns.Add("trest", "trstr");
for (int i = 0; i < 30000; i++)
{
DataGridViewRow row = new DataGridViewRow();
NoAccessCell cell = new NoAccessCell();
cell.Value = $"Row {i:00000}";
row.Cells.Add(cell);
Tester.Rows.Add(row);
}
Tester.Visible = true;
Tester.Dock = DockStyle.Fill;
this.Controls.Add(Tester);
}
class NoAccessCell : DataGridViewTextBoxCell
{
protected override AccessibleObject CreateAccessibilityInstance()
{
return new NoAccessibilityObject();
}
}
class NoAccessibilityObject : AccessibleObject
{
public override string Name
{
get => null;
set { }
}
public override AccessibleRole Role => AccessibleRole.None;
public override AccessibleObject GetChild(int index) => null;
public override int GetChildCount() => 0;
public override Rectangle Bounds => Rectangle.Empty;
public override void DoDefaultAction() { }
}
Steps to reproduce
Very easy to reproduce. Using following codes. Scroll down to the bottom. Select any row. It will take seconds to select a row.
private void Form1_Load(object sender, EventArgs e)
{
DataGridView Tester = new DataGridView();
Tester.Columns.Add("trest", "trstr");
for (int i = 0; i < 30000; i++)
{
Tester.Rows.Add($"Row {i:00000}");
}
Tester.Visible = true;
Tester.Dock = DockStyle.Fill;
this.Controls.Add(Tester);
}
.NET version
10.0.12
Did it work in .NET Framework?
Yes
Did it work in any of the earlier releases of .NET Core or .NET 5+?
No response
Issue description
Very easy to reproduce. Using following codes. Scroll down to the bottom. Select any row. It will take seconds to select a row.
The bug is in DataGridViewRowCollection. GetVisibleIndex repeats Count (30001) and DisplayIndexToRowIndex also repeats Count (30001).
GetVisibleIndex is called by DataGridViewCellAccessibleObject:Name
Following codes bypass the performance issue.
Steps to reproduce
Very easy to reproduce. Using following codes. Scroll down to the bottom. Select any row. It will take seconds to select a row.