Skip to content

Commit 1bcfb9d

Browse files
Reworking the base TextPattern implementation (#7081)
1 parent ff11a2d commit 1bcfb9d

9 files changed

+126
-106
lines changed

src/System.Windows.Forms/src/System/Windows/Forms/AccessibleObject.cs

Lines changed: 41 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -66,9 +66,6 @@ public partial class AccessibleObject :
6666
// Indicates this object is being used ONLY to wrap a system IAccessible
6767
private readonly bool _systemWrapper;
6868

69-
private UiaTextProvider? _textProvider;
70-
private UiaTextProvider2? _textProvider2;
71-
7269
// The support for the UIA Notification event begins in RS3.
7370
// Assume the UIA Notification event is available until we learn otherwise.
7471
// If we learn that the UIA Notification event is not available,
@@ -555,28 +552,60 @@ internal virtual void Toggle()
555552

556553
internal virtual void Invoke() => DoDefaultAction();
557554

558-
internal virtual UiaCore.ITextRangeProvider? DocumentRangeInternal => _textProvider?.DocumentRange;
555+
internal virtual UiaCore.ITextRangeProvider? DocumentRangeInternal
556+
{
557+
get
558+
{
559+
Debug.Fail("Not implemented. DocumentRangeInternal property should be overridden.");
560+
return null;
561+
}
562+
}
559563

560-
internal virtual UiaCore.ITextRangeProvider[]? GetTextSelection() => _textProvider?.GetSelection();
564+
internal virtual UiaCore.ITextRangeProvider[]? GetTextSelection()
565+
{
566+
Debug.Fail("Not implemented. GetTextSelection method should be overridden.");
567+
return null;
568+
}
561569

562-
internal virtual UiaCore.ITextRangeProvider[]? GetTextVisibleRanges() => _textProvider?.GetVisibleRanges();
570+
internal virtual UiaCore.ITextRangeProvider[]? GetTextVisibleRanges()
571+
{
572+
Debug.Fail("Not implemented. GetTextVisibleRanges method should be overridden.");
573+
return null;
574+
}
563575

564576
internal virtual UiaCore.ITextRangeProvider? GetTextRangeFromChild(UiaCore.IRawElementProviderSimple childElement)
565-
=> _textProvider?.RangeFromChild(childElement);
577+
{
578+
Debug.Fail("Not implemented. GetTextRangeFromChild method should be overridden.");
579+
return null;
580+
}
566581

567-
internal virtual UiaCore.ITextRangeProvider? GetTextRangeFromPoint(Point screenLocation) => _textProvider?.RangeFromPoint(screenLocation);
582+
internal virtual UiaCore.ITextRangeProvider? GetTextRangeFromPoint(Point screenLocation)
583+
{
584+
Debug.Fail("Not implemented. GetTextRangeFromPoint method should be overridden.");
585+
return null;
586+
}
568587

569588
internal virtual UiaCore.SupportedTextSelection SupportedTextSelectionInternal
570-
=> _textProvider?.SupportedTextSelection ?? UiaCore.SupportedTextSelection.None;
589+
{
590+
get
591+
{
592+
Debug.Fail("Not implemented. SupportedTextSelectionInternal property should be overridden.");
593+
return UiaCore.SupportedTextSelection.None;
594+
}
595+
}
571596

572597
internal virtual UiaCore.ITextRangeProvider? GetTextCaretRange(out BOOL isActive)
573598
{
574599
isActive = BOOL.FALSE;
575-
return _textProvider2?.GetCaretRange(out isActive);
600+
Debug.Fail("Not implemented. GetTextCaretRange method should be overridden.");
601+
return null;
576602
}
577603

578-
internal virtual UiaCore.ITextRangeProvider? GetRangeFromAnnotation(UiaCore.IRawElementProviderSimple annotationElement) =>
579-
_textProvider2?.RangeFromAnnotation(annotationElement);
604+
internal virtual UiaCore.ITextRangeProvider? GetRangeFromAnnotation(UiaCore.IRawElementProviderSimple annotationElement)
605+
{
606+
Debug.Fail("Not implemented. GetRangeFromAnnotation method should be overridden.");
607+
return null;
608+
}
580609

581610
internal virtual bool IsReadOnly => false;
582611

@@ -1744,12 +1773,6 @@ protected void UseStdAccessibleObjects(IntPtr handle, int objid)
17441773
}
17451774
}
17461775

1747-
internal void UseTextProviders(UiaTextProvider textProvider, UiaTextProvider2 textProvider2)
1748-
{
1749-
_textProvider = textProvider.OrThrowIfNull();
1750-
_textProvider2 = textProvider2.OrThrowIfNull();
1751-
}
1752-
17531776
/// <summary>
17541777
/// Performs custom navigation between parent/child/sibling accessible
17551778
/// objects. This is basically just a wrapper for GetSysChild(), that

src/System.Windows.Forms/src/System/Windows/Forms/ComboBox.ComboBoxChildEditUiaProvider.cs

Lines changed: 36 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
// The .NET Foundation licenses this file to you under the MIT license.
33
// See the LICENSE file in the project root for more information.
44

5+
using System.Drawing;
56
using System.Runtime.InteropServices;
67
using static Interop;
78

@@ -16,7 +17,7 @@ internal class ComboBoxChildEditUiaProvider : ChildAccessibleObject
1617
{
1718
private const string COMBO_BOX_EDIT_AUTOMATION_ID = "1001";
1819

19-
private readonly ComboBox _owner;
20+
private readonly ComboBox _owningComboBox;
2021
private readonly ComboBoxUiaTextProvider _textProvider;
2122
private readonly IntPtr _handle;
2223

@@ -27,10 +28,9 @@ internal class ComboBoxChildEditUiaProvider : ChildAccessibleObject
2728
/// <param name="childEditControlhandle">The child edit native window handle.</param>
2829
public ComboBoxChildEditUiaProvider(ComboBox owner, IntPtr childEditControlhandle) : base(owner, childEditControlhandle)
2930
{
30-
_owner = owner;
31+
_owningComboBox = owner;
3132
_handle = childEditControlhandle;
3233
_textProvider = new ComboBoxUiaTextProvider(owner);
33-
UseTextProviders(_textProvider, _textProvider);
3434
}
3535

3636
/// <summary>
@@ -40,22 +40,22 @@ public ComboBoxChildEditUiaProvider(ComboBox owner, IntPtr childEditControlhandl
4040
/// <returns>Returns the element in the specified direction.</returns>
4141
internal override UiaCore.IRawElementProviderFragment? FragmentNavigate(UiaCore.NavigateDirection direction)
4242
{
43-
if (!_owner.IsHandleCreated)
43+
if (!_owningComboBox.IsHandleCreated)
4444
{
4545
return null;
4646
}
4747

4848
switch (direction)
4949
{
5050
case UiaCore.NavigateDirection.Parent:
51-
return _owner.AccessibilityObject;
51+
return _owningComboBox.AccessibilityObject;
5252
case UiaCore.NavigateDirection.PreviousSibling:
53-
return _owner.DroppedDown
54-
? _owner.ChildListAccessibleObject
53+
return _owningComboBox.DroppedDown
54+
? _owningComboBox.ChildListAccessibleObject
5555
: null;
5656
case UiaCore.NavigateDirection.NextSibling:
57-
return _owner.DropDownStyle != ComboBoxStyle.Simple
58-
&& _owner.AccessibilityObject is ComboBoxAccessibleObject comboBoxAccessibleObject
57+
return _owningComboBox.DropDownStyle != ComboBoxStyle.Simple
58+
&& _owningComboBox.AccessibilityObject is ComboBoxAccessibleObject comboBoxAccessibleObject
5959
? comboBoxAccessibleObject.DropDownButtonUiaProvider
6060
: null;
6161
default:
@@ -67,12 +67,7 @@ public ComboBoxChildEditUiaProvider(ComboBox owner, IntPtr childEditControlhandl
6767
/// Gets the top level element.
6868
/// </summary>
6969
internal override UiaCore.IRawElementProviderFragmentRoot FragmentRoot
70-
{
71-
get
72-
{
73-
return _owner.AccessibilityObject;
74-
}
75-
}
70+
=> _owningComboBox.AccessibilityObject;
7671

7772
public override string Name => base.Name ?? SR.ComboBoxEditDefaultAccessibleName;
7873

@@ -88,11 +83,11 @@ internal override UiaCore.IRawElementProviderFragmentRoot FragmentRoot
8883
case UiaCore.UIA.ControlTypePropertyId:
8984
return UiaCore.UIA.EditControlTypeId;
9085
case UiaCore.UIA.HasKeyboardFocusPropertyId:
91-
return _owner.Focused;
86+
return _owningComboBox.Focused;
9287
case UiaCore.UIA.IsKeyboardFocusablePropertyId:
9388
return (State & AccessibleStates.Focusable) == AccessibleStates.Focusable;
9489
case UiaCore.UIA.IsEnabledPropertyId:
95-
return _owner.Enabled;
90+
return _owningComboBox.Enabled;
9691
case UiaCore.UIA.AutomationIdPropertyId:
9792
return COMBO_BOX_EDIT_AUTOMATION_ID;
9893
case UiaCore.UIA.NativeWindowHandlePropertyId:
@@ -128,6 +123,30 @@ internal override bool IsPatternSupported(UiaCore.UIA patternId) =>
128123
/// Gets the runtime ID.
129124
/// </summary>
130125
internal override int[] RuntimeId => new int[] { RuntimeIDFirstItem, GetHashCode() };
126+
127+
internal override UiaCore.ITextRangeProvider DocumentRangeInternal
128+
=> _textProvider.DocumentRange;
129+
130+
internal override UiaCore.ITextRangeProvider[]? GetTextSelection()
131+
=> _textProvider.GetSelection();
132+
133+
internal override UiaCore.ITextRangeProvider[]? GetTextVisibleRanges()
134+
=> _textProvider.GetVisibleRanges();
135+
136+
internal override UiaCore.ITextRangeProvider? GetTextRangeFromChild(UiaCore.IRawElementProviderSimple childElement)
137+
=> _textProvider.RangeFromChild(childElement);
138+
139+
internal override UiaCore.ITextRangeProvider? GetTextRangeFromPoint(Point screenLocation)
140+
=> _textProvider.RangeFromPoint(screenLocation);
141+
142+
internal override UiaCore.SupportedTextSelection SupportedTextSelectionInternal
143+
=> _textProvider.SupportedTextSelection;
144+
145+
internal override UiaCore.ITextRangeProvider? GetTextCaretRange(out BOOL isActive)
146+
=> _textProvider.GetCaretRange(out isActive);
147+
148+
internal override UiaCore.ITextRangeProvider GetRangeFromAnnotation(UiaCore.IRawElementProviderSimple annotationElement)
149+
=> _textProvider.RangeFromAnnotation(annotationElement);
131150
}
132151
}
133152
}

src/System.Windows.Forms/src/System/Windows/Forms/DataGridViewTextBoxEditingControl.DataGridViewTextBoxEditingControlAccessibleObject.cs

Lines changed: 2 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -11,21 +11,15 @@ partial class DataGridViewTextBoxEditingControl
1111
/// <summary>
1212
/// Defines the DataGridView TextBox EditingControl accessible object.
1313
/// </summary>
14-
internal class DataGridViewTextBoxEditingControlAccessibleObject : ControlAccessibleObject
14+
internal class DataGridViewTextBoxEditingControlAccessibleObject : TextBoxBaseAccessibleObject
1515
{
1616
/// <summary>
1717
/// The parent is changed when the editing control is attached to another editing cell.
1818
/// </summary>
1919
private AccessibleObject? _parentAccessibleObject;
20-
private readonly TextBoxBase _owningDataGridViewTextBoxEditingControl;
21-
private readonly TextBoxBaseUiaTextProvider _textProvider;
2220

2321
public DataGridViewTextBoxEditingControlAccessibleObject(DataGridViewTextBoxEditingControl ownerControl) : base(ownerControl)
24-
{
25-
_owningDataGridViewTextBoxEditingControl = ownerControl;
26-
_textProvider = new TextBoxBaseUiaTextProvider(ownerControl);
27-
UseTextProviders(_textProvider, _textProvider);
28-
}
22+
{ }
2923

3024
public override AccessibleObject? Parent => _parentAccessibleObject;
3125

@@ -72,13 +66,9 @@ internal override bool IsPatternSupported(UiaCore.UIA patternId)
7266
=> patternId switch
7367
{
7468
UiaCore.UIA.ValuePatternId => true,
75-
UiaCore.UIA.TextPatternId => true,
76-
UiaCore.UIA.TextPattern2Id => true,
7769
_ => base.IsPatternSupported(patternId)
7870
};
7971

80-
internal override bool IsReadOnly => _owningDataGridViewTextBoxEditingControl.ReadOnly;
81-
8272
/// <summary>
8373
/// Sets the parent accessible object for the node which can be added or removed to/from hierarchy nodes.
8474
/// </summary>

src/System.Windows.Forms/src/System/Windows/Forms/PropertyGridInternal/PropertyGridView.GridViewTextBox.GridViewTextBoxAccessibleObject.cs

Lines changed: 1 addition & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -11,16 +11,13 @@ internal partial class PropertyGridView
1111
{
1212
private partial class GridViewTextBox
1313
{
14-
private class GridViewTextBoxAccessibleObject : ControlAccessibleObject
14+
private class GridViewTextBoxAccessibleObject : TextBoxBaseAccessibleObject
1515
{
1616
private readonly PropertyGridView _owningPropertyGridView;
17-
private readonly TextBoxBaseUiaTextProvider _textProvider;
1817

1918
public GridViewTextBoxAccessibleObject(GridViewTextBox owner) : base(owner)
2019
{
2120
_owningPropertyGridView = owner.PropertyGridView;
22-
_textProvider = new TextBoxBaseUiaTextProvider(owner);
23-
UseTextProviders(_textProvider, _textProvider);
2421
}
2522

2623
public override AccessibleStates State
@@ -41,8 +38,6 @@ public override AccessibleStates State
4138
}
4239
}
4340

44-
internal override bool IsIAccessibleExSupported() => true;
45-
4641
/// <summary>
4742
/// Returns the element in the specified direction.
4843
/// </summary>
@@ -83,8 +78,6 @@ internal override UiaCore.IRawElementProviderFragmentRoot? FragmentRoot
8378
internal override bool IsPatternSupported(UiaCore.UIA patternId) => patternId switch
8479
{
8580
UiaCore.UIA.ValuePatternId => true,
86-
UiaCore.UIA.TextPatternId => true,
87-
UiaCore.UIA.TextPattern2Id => true,
8881
_ => base.IsPatternSupported(patternId)
8982
};
9083

src/System.Windows.Forms/src/System/Windows/Forms/TextBoxBase.TextBoxBaseAccessibleObject.cs

Lines changed: 32 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -2,36 +2,59 @@
22
// The .NET Foundation licenses this file to you under the MIT license.
33
// See the LICENSE file in the project root for more information.
44

5+
using System.Drawing;
56
using static Interop;
7+
using static Interop.UiaCore;
68

79
namespace System.Windows.Forms
810
{
911
public abstract partial class TextBoxBase
1012
{
1113
internal class TextBoxBaseAccessibleObject : ControlAccessibleObject
1214
{
13-
private readonly TextBoxBase _owningTextBoxBase;
1415
private readonly TextBoxBaseUiaTextProvider _textProvider;
1516

1617
public TextBoxBaseAccessibleObject(TextBoxBase owner) : base(owner)
1718
{
18-
_owningTextBoxBase = owner;
1919
_textProvider = new TextBoxBaseUiaTextProvider(owner);
20-
21-
UseTextProviders(_textProvider, _textProvider);
2220
}
2321

2422
internal override bool IsIAccessibleExSupported() => true;
2523

26-
internal override bool IsPatternSupported(UiaCore.UIA patternId) =>
27-
patternId switch
24+
internal override bool IsPatternSupported(UIA patternId)
25+
=> patternId switch
2826
{
29-
UiaCore.UIA.TextPatternId => true,
30-
UiaCore.UIA.TextPattern2Id => true,
27+
UIA.TextPatternId => true,
28+
UIA.TextPattern2Id => true,
3129
_ => base.IsPatternSupported(patternId)
3230
};
3331

34-
internal override bool IsReadOnly => _owningTextBoxBase.ReadOnly;
32+
internal override bool IsReadOnly
33+
=> Owner is TextBoxBase textBoxBase && textBoxBase.ReadOnly;
34+
35+
internal override ITextRangeProvider DocumentRangeInternal
36+
=> _textProvider.DocumentRange;
37+
38+
internal override ITextRangeProvider[]? GetTextSelection()
39+
=> _textProvider.GetSelection();
40+
41+
internal override ITextRangeProvider[]? GetTextVisibleRanges()
42+
=> _textProvider.GetVisibleRanges();
43+
44+
internal override ITextRangeProvider? GetTextRangeFromChild(IRawElementProviderSimple childElement)
45+
=> _textProvider.RangeFromChild(childElement);
46+
47+
internal override ITextRangeProvider? GetTextRangeFromPoint(Point screenLocation)
48+
=> _textProvider.RangeFromPoint(screenLocation);
49+
50+
internal override SupportedTextSelection SupportedTextSelectionInternal
51+
=> _textProvider.SupportedTextSelection;
52+
53+
internal override ITextRangeProvider? GetTextCaretRange(out BOOL isActive)
54+
=> _textProvider.GetCaretRange(out isActive);
55+
56+
internal override ITextRangeProvider GetRangeFromAnnotation(IRawElementProviderSimple annotationElement)
57+
=> _textProvider.RangeFromAnnotation(annotationElement);
3558
}
3659
}
3760
}

src/System.Windows.Forms/src/System/Windows/Forms/ToolStripTextBox.ToolStripTextBoxControl.cs

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -218,9 +218,7 @@ protected override void OnVisibleChanged(EventArgs e)
218218
}
219219

220220
protected override AccessibleObject CreateAccessibilityInstance()
221-
{
222-
return new ToolStripTextBoxControlAccessibleObject(this, Owner);
223-
}
221+
=> new ToolStripTextBoxControlAccessibleObject(this);
224222

225223
protected override void Dispose(bool disposing)
226224
{

0 commit comments

Comments
 (0)