1+ // (c) Copyright Microsoft Corporation.
2+ // This source is subject to the Microsoft Public License (Ms-PL).
3+ // Please see http://go.microsoft.com/fwlink/?LinkID=131993] for details.
4+ // All other rights reserved.
5+
6+ using System . Collections . Generic ;
7+ using System . Diagnostics . CodeAnalysis ;
8+ using System . Windows ;
9+ using System . Windows . Automation ;
10+ using System . Windows . Automation . Peers ;
11+ using System . Windows . Automation . Provider ;
12+
13+ namespace GitHub . UI
14+ {
15+ /// <summary>
16+ /// Exposes AutoCompleteBox types to UI Automation.
17+ /// </summary>
18+ /// <QualityBand>Stable</QualityBand>
19+ public sealed class AutoCompleteBoxAutomationPeer : FrameworkElementAutomationPeer , IValueProvider , IExpandCollapseProvider , ISelectionProvider
20+ {
21+ /// <summary>
22+ /// The name reported as the core class name.
23+ /// </summary>
24+ private const string autoCompleteBoxClassNameCore = "AutoCompleteBox" ;
25+
26+ /// <summary>
27+ /// Gets the AutoCompleteBox that owns this
28+ /// AutoCompleteBoxAutomationPeer.
29+ /// </summary>
30+ private AutoCompleteBox OwnerAutoCompleteBox
31+ {
32+ get { return ( AutoCompleteBox ) Owner ; }
33+ }
34+
35+ /// <summary>
36+ /// Gets a value indicating whether the UI automation provider allows
37+ /// more than one child element to be selected concurrently.
38+ /// </summary>
39+ /// <remarks>
40+ /// This API supports the .NET Framework infrastructure and is not
41+ /// intended to be used directly from your code.
42+ /// </remarks>
43+ /// <value>True if multiple selection is allowed; otherwise, false.</value>
44+ bool ISelectionProvider . CanSelectMultiple
45+ {
46+ get { return false ; }
47+ }
48+
49+ /// <summary>
50+ /// Gets a value indicating whether the UI automation provider
51+ /// requires at least one child element to be selected.
52+ /// </summary>
53+ /// <remarks>
54+ /// This API supports the .NET Framework infrastructure and is not
55+ /// intended to be used directly from your code.
56+ /// </remarks>
57+ /// <value>True if selection is required; otherwise, false.</value>
58+ bool ISelectionProvider . IsSelectionRequired
59+ {
60+ get { return false ; }
61+ }
62+
63+ /// <summary>
64+ /// Initializes a new instance of the AutoCompleteBoxAutomationPeer
65+ /// class.
66+ /// </summary>
67+ /// <param name="owner">
68+ /// The AutoCompleteBox that is associated with this
69+ /// AutoCompleteBoxAutomationPeer.
70+ /// </param>
71+ public AutoCompleteBoxAutomationPeer ( AutoCompleteBox owner )
72+ : base ( owner )
73+ {
74+ }
75+
76+ /// <summary>
77+ /// Gets the control type for the AutoCompleteBox that is associated
78+ /// with this AutoCompleteBoxAutomationPeer. This method is called by
79+ /// GetAutomationControlType.
80+ /// </summary>
81+ /// <returns>ComboBox AutomationControlType.</returns>
82+ protected override AutomationControlType GetAutomationControlTypeCore ( )
83+ {
84+ return AutomationControlType . ComboBox ;
85+ }
86+
87+ /// <summary>
88+ /// Gets the name of the AutoCompleteBox that is associated with this
89+ /// AutoCompleteBoxAutomationPeer. This method is called by
90+ /// GetClassName.
91+ /// </summary>
92+ /// <returns>The name AutoCompleteBox.</returns>
93+ protected override string GetClassNameCore ( )
94+ {
95+ return autoCompleteBoxClassNameCore ;
96+ }
97+
98+ /// <summary>
99+ /// Gets the control pattern for the AutoCompleteBox that is associated
100+ /// with this AutoCompleteBoxAutomationPeer.
101+ /// </summary>
102+ /// <param name="patternInterface">The desired PatternInterface.</param>
103+ /// <returns>The desired AutomationPeer or null.</returns>
104+ public override object GetPattern ( PatternInterface patternInterface )
105+ {
106+ object iface = null ;
107+ var owner = OwnerAutoCompleteBox ;
108+
109+ if ( patternInterface == PatternInterface . Value )
110+ {
111+ iface = this ;
112+ }
113+ else if ( patternInterface == PatternInterface . ExpandCollapse )
114+ {
115+ iface = this ;
116+ }
117+ else if ( owner . SelectionAdapter != null )
118+ {
119+ var peer = owner . SelectionAdapter . CreateAutomationPeer ( ) ;
120+ if ( peer != null )
121+ {
122+ iface = peer . GetPattern ( patternInterface ) ;
123+ }
124+ }
125+
126+ return iface ?? base . GetPattern ( patternInterface ) ;
127+ }
128+
129+ /// <summary>
130+ /// Blocking method that returns after the element has been expanded.
131+ /// </summary>
132+ /// <remarks>
133+ /// This API supports the .NET Framework infrastructure and is not
134+ /// intended to be used directly from your code.
135+ /// </remarks>
136+ void IExpandCollapseProvider . Expand ( )
137+ {
138+ if ( ! IsEnabled ( ) )
139+ {
140+ throw new ElementNotEnabledException ( ) ;
141+ }
142+
143+ OwnerAutoCompleteBox . IsDropDownOpen = true ;
144+ }
145+
146+ /// <summary>
147+ /// Blocking method that returns after the element has been collapsed.
148+ /// </summary>
149+ /// <remarks>
150+ /// This API supports the .NET Framework infrastructure and is not
151+ /// intended to be used directly from your code.
152+ /// </remarks>
153+ void IExpandCollapseProvider . Collapse ( )
154+ {
155+ if ( ! IsEnabled ( ) )
156+ {
157+ throw new ElementNotEnabledException ( ) ;
158+ }
159+
160+ OwnerAutoCompleteBox . IsDropDownOpen = false ;
161+ }
162+
163+ /// <summary>
164+ /// Gets an element's current Collapsed or Expanded state.
165+ /// </summary>
166+ /// <remarks>
167+ /// This API supports the .NET Framework infrastructure and is not
168+ /// intended to be used directly from your code.
169+ /// </remarks>
170+ ExpandCollapseState IExpandCollapseProvider . ExpandCollapseState
171+ {
172+ get
173+ {
174+ return OwnerAutoCompleteBox . IsDropDownOpen ? ExpandCollapseState . Expanded : ExpandCollapseState . Collapsed ;
175+ }
176+ }
177+
178+ /// <summary>
179+ /// Raises the ExpandCollapse automation event.
180+ /// </summary>
181+ /// <param name="oldValue">The old value.</param>
182+ /// <param name="newValue">The new value.</param>
183+ internal void RaiseExpandCollapseAutomationEvent ( bool oldValue , bool newValue )
184+ {
185+ RaisePropertyChangedEvent (
186+ ExpandCollapsePatternIdentifiers . ExpandCollapseStateProperty ,
187+ oldValue ? ExpandCollapseState . Expanded : ExpandCollapseState . Collapsed ,
188+ newValue ? ExpandCollapseState . Expanded : ExpandCollapseState . Collapsed ) ;
189+ }
190+
191+ /// <summary>
192+ /// Sets the value of a control.
193+ /// </summary>
194+ /// <param name="value">The value to set. The provider is responsible
195+ /// for converting the value to the appropriate data type.</param>
196+ void IValueProvider . SetValue ( string value )
197+ {
198+ OwnerAutoCompleteBox . Text = value ;
199+ }
200+
201+ /// <summary>
202+ /// Gets a value indicating whether the value of a control is
203+ /// read-only.
204+ /// </summary>
205+ /// <value>True if the value is read-only; false if it can be modified.</value>
206+ bool IValueProvider . IsReadOnly
207+ {
208+ get
209+ {
210+ return ! OwnerAutoCompleteBox . IsEnabled ;
211+ }
212+ }
213+
214+ /// <summary>
215+ /// Gets the value of the control.
216+ /// </summary>
217+ /// <value>The value of the control.</value>
218+ string IValueProvider . Value
219+ {
220+ get
221+ {
222+ return OwnerAutoCompleteBox . Text ?? string . Empty ;
223+ }
224+ }
225+
226+ /// <summary>
227+ /// Gets the collection of child elements of the AutoCompleteBox that
228+ /// are associated with this AutoCompleteBoxAutomationPeer. This method
229+ /// is called by GetChildren.
230+ /// </summary>
231+ /// <returns>
232+ /// A collection of automation peer elements, or an empty collection
233+ /// if there are no child elements.
234+ /// </returns>
235+ [ SuppressMessage ( "Microsoft.Design" , "CA1002:DoNotExposeGenericLists" , Justification = "Required by automation" ) ]
236+ protected override List < AutomationPeer > GetChildrenCore ( )
237+ {
238+ var children = new List < AutomationPeer > ( ) ;
239+ var owner = OwnerAutoCompleteBox ;
240+
241+ // TextBox part.
242+ var textBox = owner . TextBox ;
243+ if ( textBox != null )
244+ {
245+ var peer = CreatePeerForElement ( textBox . Control ) ;
246+ if ( peer != null )
247+ {
248+ children . Insert ( 0 , peer ) ;
249+ }
250+ }
251+
252+ // Include SelectionAdapter's children.
253+ if ( owner . SelectionAdapter != null )
254+ {
255+ var selectionAdapterPeer = owner . SelectionAdapter . CreateAutomationPeer ( ) ;
256+ if ( selectionAdapterPeer != null )
257+ {
258+ var listChildren = selectionAdapterPeer . GetChildren ( ) ;
259+ if ( listChildren != null )
260+ {
261+ children . AddRange ( listChildren ) ;
262+ }
263+ }
264+ }
265+
266+ return children ;
267+ }
268+
269+ /// <summary>
270+ /// Retrieves a UI automation provider for each child element that is
271+ /// selected.
272+ /// </summary>
273+ /// <returns>An array of UI automation providers.</returns>
274+ /// <remarks>
275+ /// This API supports the .NET Framework infrastructure and is not
276+ /// intended to be used directly from your code.
277+ /// </remarks>
278+ IRawElementProviderSimple [ ] ISelectionProvider . GetSelection ( )
279+ {
280+ if ( OwnerAutoCompleteBox . SelectionAdapter != null )
281+ {
282+ var selectedItem = OwnerAutoCompleteBox . SelectionAdapter . SelectedItem ;
283+ if ( selectedItem != null )
284+ {
285+ var uie = selectedItem as UIElement ;
286+ if ( uie != null )
287+ {
288+ var peer = CreatePeerForElement ( uie ) ;
289+ if ( peer != null )
290+ {
291+ return new [ ] { ProviderFromPeer ( peer ) } ;
292+ }
293+ }
294+ }
295+ }
296+
297+ return new IRawElementProviderSimple [ ] { } ;
298+ }
299+ }
300+ }
0 commit comments