Skip to content

Commit 5d67166

Browse files
authored
[release/8.0] Fix #12661 Null Reference Exception: System.Windows.Forms.TabControl<WmSelChange> (#12731)
Fixes 12661 Customer Impact A customer reported a crash in their application that uses WinForms TabControl and requested a fix in NET8 release. Application is running under accessibility tools and is removing TabPages from a control dynamically. When the selected page is removed, the selection moves to the next page and the corresponding accessibility event is queued using BeginInvoke to be raised. If by the time the event is raised, the page is removed, a NullReferenceException is thrown. No workaround is available. Fix Test if the selected page is still available before raising the accessibility event inside the BeginInvoke delegate.
1 parent 1939cce commit 5d67166

File tree

2 files changed

+42
-1
lines changed

2 files changed

+42
-1
lines changed

src/System.Windows.Forms/src/System/Windows/Forms/TabControl.cs

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1970,7 +1970,14 @@ private bool WmSelChange()
19701970
if (IsAccessibilityObjectCreated && SelectedTab?.ParentInternal is TabControl)
19711971
{
19721972
SelectedTab.TabAccessibilityObject.RaiseAutomationEvent(UiaCore.UIA.SelectionItem_ElementSelectedEventId);
1973-
BeginInvoke((MethodInvoker)(() => SelectedTab.TabAccessibilityObject.RaiseAutomationEvent(UiaCore.UIA.AutomationFocusChangedEventId)));
1973+
BeginInvoke((MethodInvoker)(() =>
1974+
{
1975+
if (IsAccessibilityObjectCreated && SelectedTab?.ParentInternal is TabControl &&
1976+
!SelectedTab.IsDisposed && SelectedTab.TabAccessibilityObject is not null)
1977+
{
1978+
SelectedTab.TabAccessibilityObject.RaiseAutomationEvent(UiaCore.UIA.AutomationFocusChangedEventId);
1979+
}
1980+
}));
19741981
}
19751982
}
19761983
else

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

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5704,6 +5704,40 @@ public void TabControl_Invokes_SetToolTip_IfExternalToolTipIsSet()
57045704
Assert.Equal(text, actual);
57055705
}
57065706

5707+
[WinFormsFact]
5708+
public void TabControl_WmSelChange_SelectedTabIsNull_DoesNotThrowException()
5709+
{
5710+
using Form form = new();
5711+
using TabControl control = new();
5712+
using TabPage page1 = new("text1");
5713+
control.TabPages.Add(page1);
5714+
_ = control.AccessibilityObject;
5715+
5716+
form.Controls.Add(control);
5717+
form.Show();
5718+
control.SelectedIndex = 0;
5719+
5720+
Action act = () => control.TestAccessor().Dynamic.WmSelChange();
5721+
try
5722+
{
5723+
act();
5724+
}
5725+
catch (Exception ex)
5726+
{
5727+
Assert.Fail($"Expected no exception, but got: {ex}");
5728+
}
5729+
5730+
control.TabPages.Clear();
5731+
5732+
var exception = Record.Exception(() =>
5733+
{
5734+
Application.DoEvents();
5735+
Thread.Sleep(100);
5736+
});
5737+
5738+
Assert.Null(exception);
5739+
}
5740+
57075741
private class SubTabPage : TabPage
57085742
{
57095743
}

0 commit comments

Comments
 (0)