Skip to content

Commit 87c7908

Browse files
[release/9.0] Fix #12661 Null Reference Exception: System.Windows.Forms.TabControl.<WmSelChange> (#12728)
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 d592148 commit 87c7908

File tree

2 files changed

+35
-1
lines changed

2 files changed

+35
-1
lines changed

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

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1956,7 +1956,14 @@ private bool WmSelChange()
19561956
if (IsAccessibilityObjectCreated && SelectedTab?.ParentInternal is TabControl)
19571957
{
19581958
SelectedTab.TabAccessibilityObject.RaiseAutomationEvent(UIA_EVENT_ID.UIA_SelectionItem_ElementSelectedEventId);
1959-
BeginInvoke((MethodInvoker)(() => SelectedTab.TabAccessibilityObject.RaiseAutomationEvent(UIA_EVENT_ID.UIA_AutomationFocusChangedEventId)));
1959+
BeginInvoke((MethodInvoker)(() =>
1960+
{
1961+
if (IsAccessibilityObjectCreated && SelectedTab?.ParentInternal is TabControl &&
1962+
!SelectedTab.IsDisposed && SelectedTab.TabAccessibilityObject is not null)
1963+
{
1964+
SelectedTab.TabAccessibilityObject.RaiseAutomationEvent(UIA_EVENT_ID.UIA_AutomationFocusChangedEventId);
1965+
}
1966+
}));
19601967
}
19611968
}
19621969
else

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

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5703,6 +5703,33 @@ public void TabControl_Invokes_SetToolTip_IfExternalToolTipIsSet()
57035703
Assert.Equal(text, actual);
57045704
}
57055705

5706+
[WinFormsFact]
5707+
public void TabControl_WmSelChange_SelectedTabIsNull_DoesNotThrowException()
5708+
{
5709+
using Form form = new();
5710+
using TabControl control = new();
5711+
using TabPage page1 = new("text1");
5712+
control.TabPages.Add(page1);
5713+
_ = control.AccessibilityObject;
5714+
5715+
form.Controls.Add(control);
5716+
form.Show();
5717+
control.SelectedIndex = 0;
5718+
5719+
Action act = () => control.TestAccessor().Dynamic.WmSelChange();
5720+
act.Should().NotThrow();
5721+
5722+
control.TabPages.Clear();
5723+
5724+
var exception = Record.Exception(() =>
5725+
{
5726+
Application.DoEvents();
5727+
Thread.Sleep(100);
5728+
});
5729+
5730+
exception.Should().BeNull();
5731+
}
5732+
57065733
private class SubTabPage : TabPage
57075734
{
57085735
}

0 commit comments

Comments
 (0)