Skip to content

Commit

Permalink
[release/8.0] Fix #12661 Null Reference Exception: System.Windows.For…
Browse files Browse the repository at this point in the history
…ms.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.
LeafShi1 authored Jan 8, 2025

Verified

This commit was created on GitHub.com and signed with GitHub’s verified signature.
1 parent 1939cce commit 5d67166
Showing 2 changed files with 42 additions and 1 deletion.
Original file line number Diff line number Diff line change
@@ -1970,7 +1970,14 @@ private bool WmSelChange()
if (IsAccessibilityObjectCreated && SelectedTab?.ParentInternal is TabControl)
{
SelectedTab.TabAccessibilityObject.RaiseAutomationEvent(UiaCore.UIA.SelectionItem_ElementSelectedEventId);
BeginInvoke((MethodInvoker)(() => SelectedTab.TabAccessibilityObject.RaiseAutomationEvent(UiaCore.UIA.AutomationFocusChangedEventId)));
BeginInvoke((MethodInvoker)(() =>
{
if (IsAccessibilityObjectCreated && SelectedTab?.ParentInternal is TabControl &&
!SelectedTab.IsDisposed && SelectedTab.TabAccessibilityObject is not null)
{
SelectedTab.TabAccessibilityObject.RaiseAutomationEvent(UiaCore.UIA.AutomationFocusChangedEventId);
}
}));
}
}
else
Original file line number Diff line number Diff line change
@@ -5704,6 +5704,40 @@ public void TabControl_Invokes_SetToolTip_IfExternalToolTipIsSet()
Assert.Equal(text, actual);
}

[WinFormsFact]
public void TabControl_WmSelChange_SelectedTabIsNull_DoesNotThrowException()
{
using Form form = new();
using TabControl control = new();
using TabPage page1 = new("text1");
control.TabPages.Add(page1);
_ = control.AccessibilityObject;

form.Controls.Add(control);
form.Show();
control.SelectedIndex = 0;

Action act = () => control.TestAccessor().Dynamic.WmSelChange();
try
{
act();
}
catch (Exception ex)
{
Assert.Fail($"Expected no exception, but got: {ex}");
}

control.TabPages.Clear();

var exception = Record.Exception(() =>
{
Application.DoEvents();
Thread.Sleep(100);
});

Assert.Null(exception);
}

private class SubTabPage : TabPage
{
}

0 comments on commit 5d67166

Please sign in to comment.