Files
OpenNest/OpenNest.WinForms.Tests/Controls/GridStyleTests.cs
T
ajandClaude Opus 5.5 2e17dd7bc4 fix(desktop): size grid columns before they are first painted
Grids opened at their designer widths and jumped a moment later, because
GridStyle waited for the first paint with rows before measuring them.
Columns now measure their header and first 50 rows directly: at handle
creation when the rows are already there, otherwise in a call posted when
rows arrive, which runs after the filling code and before the repaint.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-26 09:46:42 -04:00

104 lines
3.8 KiB
C#

using System.Windows.Forms;
using OpenNest.Controls;
namespace OpenNest.WinForms.Tests.Controls;
public class GridStyleTests
{
[Fact]
public void ColumnsSizeToFirstContentThenKeepTheUsersWidths() => ArchUnitsTests.RunSta(() =>
{
using var form = new Form { Width = 1200, Height = 400, ShowInTaskbar = false };
var grid = GridStyle.Apply(new DataGridView { Dock = DockStyle.Fill, AllowUserToAddRows = false });
var shortColumn = new DataGridViewTextBoxColumn { HeaderText = "Qty", Width = 300 };
var longColumn = new DataGridViewTextBoxColumn { HeaderText = "Name", Width = 40 };
var hugeColumn = new DataGridViewTextBoxColumn { HeaderText = "Notes", Width = 40 };
grid.Columns.AddRange(shortColumn, longColumn, hugeColumn);
form.Controls.Add(grid);
form.Show();
Pump(grid);
Assert.Equal(300, shortColumn.Width); // no rows yet: nothing is measured
grid.Rows.Add("1", "A fairly long drawing name", new string('W', 200));
Pump(grid);
Assert.True(shortColumn.Width < 300);
Assert.True(longColumn.Width > 40);
Assert.Equal(400, hugeColumn.Width);
Assert.All(grid.Columns.Cast<DataGridViewColumn>(), column =>
{
Assert.Equal(DataGridViewAutoSizeColumnMode.None, column.InheritedAutoSizeMode);
Assert.True(column.Resizable == DataGridViewTriState.True || column.Resizable == DataGridViewTriState.NotSet);
});
longColumn.Width = 77;
grid.Rows.Add("2", new string('X', 80), "");
Pump(grid);
Assert.Equal(77, longColumn.Width);
});
[Fact]
public void RowsFilledBeforeTheFormOpensArePaintedAtTheirFinalWidths() => ArchUnitsTests.RunSta(() =>
{
using var form = new Form { Width = 1200, Height = 400, ShowInTaskbar = false };
var grid = GridStyle.Apply(new DataGridView { Dock = DockStyle.Fill });
var column = new DataGridViewTextBoxColumn { HeaderText = "Name", Width = 40 };
grid.Columns.Add(column);
for (var i = 0; i < 20; i++)
grid.Rows.Add(i == 10 ? "A fairly long drawing name" : "A");
form.Controls.Add(grid);
var firstPaintWidth = WidthAtFirstPaint(grid, column);
form.Show();
Application.DoEvents();
Pump(grid);
Assert.True(column.Width > 40);
Assert.Equal(column.Width, firstPaintWidth());
});
[Fact]
public void RowsAddedAfterTheFormOpensArePaintedAtTheirFinalWidths() => ArchUnitsTests.RunSta(() =>
{
using var form = new Form { Width = 1200, Height = 400, ShowInTaskbar = false };
var grid = GridStyle.Apply(new DataGridView { Dock = DockStyle.Fill, AllowUserToAddRows = false });
var column = new DataGridViewTextBoxColumn { HeaderText = "Name", Width = 40 };
grid.Columns.Add(column);
form.Controls.Add(grid);
form.Show();
Pump(grid);
// One row at a time, as most grids fill: the long name is not the first row.
grid.Rows.Add("A");
grid.Rows.Add("A fairly long drawing name");
var firstPaintWidth = WidthAtFirstPaint(grid, column);
Application.DoEvents();
Pump(grid);
Assert.True(column.Width > 40);
Assert.Equal(column.Width, firstPaintWidth());
});
private static Func<int> WidthAtFirstPaint(DataGridView grid, DataGridViewColumn column)
{
var width = -1;
void OnPaint(object sender, PaintEventArgs e)
{
grid.Paint -= OnPaint;
width = column.Width;
}
grid.Paint += OnPaint;
return () => width;
}
private static void Pump(Control control)
{
for (var i = 0; i < 5; i++)
{
control.Refresh();
Application.DoEvents();
}
}
}