使用 UI 自動化將內容加入至文字方塊
注意
本文件適用對象為 .NET Framework 開發人員,其想要使用 System.Windows.Automation 命名空間中定義的受控 UI 自動化類別。 如需 UI 自動化的最新資訊,請參閱 Windows 自動化 API:UI 自動化。
本主題包含範例程式碼,示範如何使用 Microsoft UI 自動化,將文字插入單行文字方塊。 為 UI 自動化不適用的多行和 RTF 控制項提供替代方法。 為了進行比較,此範例也會示範如何使用 Win32 方法來完成相同的結果。
範例
下列範例會逐步執行目標應用程式中的文字控制項序列。 每個文字控制項都會進行測試,以查看是否可以使用 TryGetCurrentPattern 方法從其中取得 ValuePattern 物件。 如果文字控制項確實支援 ValuePattern,則會使用 SetValue 方法,將使用者定義的字串插入文字控制項。 否則,使用 SendKeys.SendWait 方法。
///--------------------------------------------------------------------
/// <summary>
/// Sets the values of the text controls using managed methods.
/// </summary>
/// <param name="s">The string to be inserted.</param>
///--------------------------------------------------------------------
private void SetValueWithUIAutomation(string s)
{
foreach (AutomationElement control in textControls)
{
InsertTextUsingUIAutomation(control, s);
}
}
///--------------------------------------------------------------------
/// <summary>
/// Inserts a string into each text control of interest.
/// </summary>
/// <param name="element">A text control.</param>
/// <param name="value">The string to be inserted.</param>
///--------------------------------------------------------------------
private void InsertTextUsingUIAutomation(AutomationElement element,
string value)
{
try
{
// Validate arguments / initial setup
if (value == null)
throw new ArgumentNullException(
"String parameter must not be null.");
if (element == null)
throw new ArgumentNullException(
"AutomationElement parameter must not be null");
// A series of basic checks prior to attempting an insertion.
//
// Check #1: Is control enabled?
// An alternative to testing for static or read-only controls
// is to filter using
// PropertyCondition(AutomationElement.IsEnabledProperty, true)
// and exclude all read-only text controls from the collection.
if (!element.Current.IsEnabled)
{
throw new InvalidOperationException(
"The control with an AutomationID of "
+ element.Current.AutomationId.ToString()
+ " is not enabled.\n\n");
}
// Check #2: Are there styles that prohibit us
// from sending text to this control?
if (!element.Current.IsKeyboardFocusable)
{
throw new InvalidOperationException(
"The control with an AutomationID of "
+ element.Current.AutomationId.ToString()
+ "is read-only.\n\n");
}
// Once you have an instance of an AutomationElement,
// check if it supports the ValuePattern pattern.
object valuePattern = null;
// Control does not support the ValuePattern pattern
// so use keyboard input to insert content.
//
// NOTE: Elements that support TextPattern
// do not support ValuePattern and TextPattern
// does not support setting the text of
// multi-line edit or document controls.
// For this reason, text input must be simulated
// using one of the following methods.
//
if (!element.TryGetCurrentPattern(
ValuePattern.Pattern, out valuePattern))
{
feedbackText.Append("The control with an AutomationID of ")
.Append(element.Current.AutomationId.ToString())
.Append(" does not support ValuePattern.")
.AppendLine(" Using keyboard input.\n");
// Set focus for input functionality and begin.
element.SetFocus();
// Pause before sending keyboard input.
Thread.Sleep(100);
// Delete existing content in the control and insert new content.
SendKeys.SendWait("^{HOME}"); // Move to start of control
SendKeys.SendWait("^+{END}"); // Select everything
SendKeys.SendWait("{DEL}"); // Delete selection
SendKeys.SendWait(value);
}
// Control supports the ValuePattern pattern so we can
// use the SetValue method to insert content.
else
{
feedbackText.Append("The control with an AutomationID of ")
.Append(element.Current.AutomationId.ToString())
.Append((" supports ValuePattern."))
.AppendLine(" Using ValuePattern.SetValue().\n");
// Set focus for input functionality and begin.
element.SetFocus();
((ValuePattern)valuePattern).SetValue(value);
}
}
catch (ArgumentNullException exc)
{
feedbackText.Append(exc.Message);
}
catch (InvalidOperationException exc)
{
feedbackText.Append(exc.Message);
}
finally
{
Feedback(feedbackText.ToString());
}
}
'' --------------------------------------------------------------------
'' <summary>
'' Sets the values of the text controls using managed methods.
'' </summary>
'' <param name="s">The string to be inserted.</param>
'' --------------------------------------------------------------------
Private Sub SetValueWithUIAutomation(ByVal s As String)
Dim control As AutomationElement
For Each control In textControls
InsertTextWithUIAutomation(control, s)
Next control
End Sub
'' --------------------------------------------------------------------
'' <summary>
'' Inserts a string into each text control of interest.
'' </summary>
'' <param name="element">A text control.</param>
'' <param name="value">The string to be inserted.</param>
'' --------------------------------------------------------------------
Private Sub InsertTextWithUIAutomation( _
ByVal element As AutomationElement, ByVal value As String)
Try
' Validate arguments / initial setup
If value Is Nothing Then
Throw New ArgumentNullException( _
"String parameter must not be null.")
End If
If element Is Nothing Then
Throw New ArgumentNullException( _
"AutomationElement parameter must not be null")
End If
' A series of basic checks prior to attempting an insertion.
'
' Check #1: Is control enabled?
' An alternative to testing for static or read-only controls
' is to filter using
' PropertyCondition(AutomationElement.IsEnabledProperty, true)
' and exclude all read-only text controls from the collection.
If Not element.Current.IsEnabled Then
Throw New InvalidOperationException( _
"The control with an AutomationID of " + _
element.Current.AutomationId.ToString() + _
" is not enabled." + vbLf + vbLf)
End If
' Check #2: Are there styles that prohibit us
' from sending text to this control?
If Not element.Current.IsKeyboardFocusable Then
Throw New InvalidOperationException( _
"The control with an AutomationID of " + _
element.Current.AutomationId.ToString() + _
"is read-only." + vbLf + vbLf)
End If
' Once you have an instance of an AutomationElement,
' check if it supports the ValuePattern pattern.
Dim targetValuePattern As Object = Nothing
' Control does not support the ValuePattern pattern
' so use keyboard input to insert content.
'
' NOTE: Elements that support TextPattern
' do not support ValuePattern and TextPattern
' does not support setting the text of
' multi-line edit or document controls.
' For this reason, text input must be simulated
' using one of the following methods.
'
If Not element.TryGetCurrentPattern(ValuePattern.Pattern, targetValuePattern) Then
feedbackText.Append("The control with an AutomationID of ") _
.Append(element.Current.AutomationId.ToString()) _
.Append(" does not support ValuePattern."). _
AppendLine(" Using keyboard input.").AppendLine()
' Set focus for input functionality and begin.
element.SetFocus()
' Pause before sending keyboard input.
Thread.Sleep(100)
' Delete existing content in the control and insert new content.
SendKeys.SendWait("^{HOME}") ' Move to start of control
SendKeys.SendWait("^+{END}") ' Select everything
SendKeys.SendWait("{DEL}") ' Delete selection
SendKeys.SendWait(value)
Else
' Control supports the ValuePattern pattern so we can
' use the SetValue method to insert content.
feedbackText.Append("The control with an AutomationID of ") _
.Append(element.Current.AutomationId.ToString()) _
.Append(" supports ValuePattern.") _
.AppendLine(" Using ValuePattern.SetValue().").AppendLine()
' Set focus for input functionality and begin.
element.SetFocus()
Dim valueControlPattern As ValuePattern = _
DirectCast(targetValuePattern, ValuePattern)
valueControlPattern.SetValue(value)
End If
Catch exc As ArgumentNullException
feedbackText.Append(exc.Message)
Catch exc As InvalidOperationException
feedbackText.Append(exc.Message)
Finally
Feedback(feedbackText.ToString())
End Try
End Sub