From e0dfc25524e074fe47d67f83086c3d5cb7e3476b Mon Sep 17 00:00:00 2001 From: mark-sil <83427558+mark-sil@users.noreply.github.com> Date: Wed, 11 Nov 2026 21:30:05 -0500 Subject: [PATCH] Fix crash leaving a tool after switching from New with an empty list Switching the UI mode from New to the WinForms view while a detail tool shows no record now leaves the tool safe to leave or close. Until now the detail view's DataTree was never set up on that path, so going to another tool, or closing the window, crashed with a NullReferenceException in DataTree.SetCurrentSlicePropertyNames. The DataTree is now set up when the empty tool first shows in the WinForms view, as it already is when the tool starts in that view or shows a record. Co-Authored-By: Claude Opus 5.5 --- Src/xWorks/RecordEditView.cs | 2 ++ .../Hosting/RecordEditViewSwitchTests.cs | 23 +++++++++++++++++++ 2 files changed, 25 insertions(+) diff --git a/Src/xWorks/RecordEditView.cs b/Src/xWorks/RecordEditView.cs index 04eacb3deb..b3c740b461 100644 --- a/Src/xWorks/RecordEditView.cs +++ b/Src/xWorks/RecordEditView.cs @@ -411,6 +411,8 @@ bool ShowRecordOnIdle(object parameter) } else { + // Switching from New with no record leaves the tree uninitialized. + EnsureDataTreeInitialized(); EnsureDataTreeVisible(); m_dataEntryForm.Hide(); m_dataEntryForm.Reset(); // in case user deleted the object it was based upon. diff --git a/Src/xWorks/xWorksTests/Avalonia/Hosting/RecordEditViewSwitchTests.cs b/Src/xWorks/xWorksTests/Avalonia/Hosting/RecordEditViewSwitchTests.cs index 7d6aaca7a2..33e66a0587 100644 --- a/Src/xWorks/xWorksTests/Avalonia/Hosting/RecordEditViewSwitchTests.cs +++ b/Src/xWorks/xWorksTests/Avalonia/Hosting/RecordEditViewSwitchTests.cs @@ -194,6 +194,29 @@ public void RegisteredRecordEditTools_ResolveToAvalonia_WhenUIModeIsNew(string t toolValue); } + // Switching from New to the WinForms view with no current record must still initialize + // the DataTree: leaving the tool (or closing the window) calls its PrepareToGoAway. + [Test] + public void FlipNewToLegacy_WithNoCurrentRecord_PrepareToGoAwaySucceeds() + { + m_propertyTable.SetProperty("UIMode", "New", true); + m_propertyTable.SetPropertyPersistence("UIMode", false); + + LoadRecordEditView("ProdRestrictEdit"); + DrainMediatorAndIdleQueues(); + + var control = m_propertyTable.GetValue("currentContentControlObject", null) as RecordEditView; + Assert.That(control, Is.Not.Null); + Assert.That(control.Clerk.CurrentObject, Is.Null, "precondition: the list is empty"); + Assert.That(GetPrivateFieldValue(control, "m_activeUIFramework"), Is.EqualTo(UIFramework.Avalonia)); + + m_propertyTable.SetProperty("UIMode", "Legacy", true); + DrainMediatorAndIdleQueues(); + Assert.That(GetPrivateFieldValue(control, "m_activeUIFramework"), Is.EqualTo(UIFramework.Legacy)); + + Assert.That(control.PrepareToGoAway(), Is.True); + } + // LT-22811: View > Refresh and closing the Styles dialog reach the Avalonia view through // RefreshDisplay, which recomposes it at Normal's new size. [Test]