From 3ba8f4e3b2e3bbee5f603d3bc0905dd929e920db Mon Sep 17 00:00:00 2001 From: AJ Isaacs Date: Sun, 4 Oct 2026 18:24:03 -0400 Subject: [PATCH] fix(desktop): avoid AutoNest stock grid hang and name the busy export target DataGridView.EndEdit() hangs/throws instead of returning false when CellValidating has already cancelled the pending edit, so an unparsable stock size froze TryGetPlateOptions. Validate the pending edit text ourselves before ever asking EndEdit() to commit or discard it. Also include the nest name in the export-busy message, matching how the invalid-name rejection already does. Co-Authored-By: Claude Sonnet 5 --- OpenNest/Forms/AutoNestForm.cs | 40 +++++++++++++++++++++++++++++++++- OpenNest/Forms/EditNestForm.cs | 2 +- 2 files changed, 40 insertions(+), 2 deletions(-) diff --git a/OpenNest/Forms/AutoNestForm.cs b/OpenNest/Forms/AutoNestForm.cs index ad09e6d..bd297f0 100644 --- a/OpenNest/Forms/AutoNestForm.cs +++ b/OpenNest/Forms/AutoNestForm.cs @@ -158,6 +158,7 @@ namespace OpenNest.Forms ); plateGrid.CellValidating += PlateGrid_CellValidating; + plateGrid.DataError += PlateGrid_DataError; } private void LoadDrawings(Nest nest) @@ -214,7 +215,36 @@ namespace OpenNest.Forms { options = new List(); error = null; - if (!plateGrid.EndEdit()) + + // CellValidating cancels an unparsable size and leaves the cell in edit mode; + // calling EndEdit() on that cancelled edit hangs/throws instead of returning + // false for it. Catch an unparsable pending edit ourselves first so EndEdit() + // is never asked to commit or discard it. + if ( + plateGrid.IsCurrentCellInEditMode + && plateGrid.CurrentCell != null + && plateGrid.Columns[plateGrid.CurrentCell.ColumnIndex].DataPropertyName == "Size" + && plateGrid.EditingControl != null + ) + { + var pending = plateGrid.EditingControl.Text; + if (!string.IsNullOrWhiteSpace(pending) && !TryParseSize(pending, out _, out _)) + { + error = $"Invalid stock size '{Preview(pending)}'. Enter positive dimensions as W x L."; + return false; + } + } + + bool committed; + try + { + committed = plateGrid.EndEdit(); + } + catch (InvalidOperationException) + { + committed = false; + } + if (!committed) { var value = plateGrid.EditingControl?.Text ?? plateGrid.CurrentCell?.Value?.ToString(); error = $"Invalid stock size '{Preview(value)}'. Enter positive dimensions as W x L."; @@ -424,6 +454,14 @@ namespace OpenNest.Forms ); } + // CellValidating and TryGetPlateOptions already surface invalid sizes to the user; + // this only stops the grid from throwing when a commit is forced outside that path + // (e.g. a BindingContext change while a cell is mid-edit). + private void PlateGrid_DataError(object sender, DataGridViewDataErrorEventArgs e) + { + e.ThrowException = false; + } + private DataGridViewItem GetDataGridViewItem(Drawing dwg) { var item = new DataGridViewItem(); diff --git a/OpenNest/Forms/EditNestForm.cs b/OpenNest/Forms/EditNestForm.cs index 3722276..474c414 100644 --- a/OpenNest/Forms/EditNestForm.cs +++ b/OpenNest/Forms/EditNestForm.cs @@ -520,7 +520,7 @@ namespace OpenNest.Forms if (isJobBusy() || IsReportTargetBusy(nest)) throw new InvalidOperationException( - "Finish or cancel the current nesting or plate action before exporting the nest report." + $"Finish or cancel the current nesting or plate action before exporting the report for '{nest.Name}'." ); return new NestReportTargets(nest, $"{nest.Name}.report.pdf");