ValuePattern
ValuePattern是UI Automation中最常见的Pattern之一,Winform和WPF的TextBox控件都支持ValuePattern。
ValuePattern的一个重要的方法是SetValue,在允许调用 SetValue 之前,控件应将其 IsEnabledProperty 设置为 true 并将其 IsReadOnlyProperty 设置为 false。
通过ValuePattern的Current属性可以获得控件的value和IsReadOnly属性。
实现 Value 控件模式时,请注意以下准则和约定:
如果任何项的值是可编辑的,则诸如 ListItem 和 TreeItem 等控件必须支持 ValuePattern,而不管控件的当前编辑模式如何。如果子项是可编辑的,则父控件还必须支持 ValuePattern。
下面的例子是通过ValuePattern来给TextBox设置和获取值:
Code
1using System;
2using System.Text;
3using System.Diagnostics;
4using System.Threading;
5using System.Windows.Automation;
6
7namespace UIATest
8{
9 class Program
10 {
11 static void Main(string[] args)
12 {
13 Process process = Process.Start(@"F:\CSharpDotNet\AutomationTest\ATP\WpfApp\bin\Debug\WpfApp.exe");
14 int processId = process.Id;
15 AutomationElement element = FindElementById(processId, "textBox1");
16 ValuePattern currentPattern = GetValuePattern(element);
17 Console.WriteLine("Is read only:'{0}', TextBox text is:'{1}'", currentPattern.Current.IsReadOnly, currentPattern.Current.Value);
18 currentPattern.SetValue("KadenKang");
19 Console.WriteLine("After using the SetValue, the TextBox value is '{0}'", currentPattern.Current.Value);
20
21 }
22
23 /**//// <summary>
24 /// Get the automation elemention of current form.
25 /// </summary>
26 /// <param name="processId">Process Id</param>
27 /// <returns>Target element</returns>
28 public static AutomationElement FindWindowByProcessId(int processId)
29 {
30 AutomationElement targetWindow = null;
31 int count = 0;
32 try
33 {
34 Process p = Process.GetProcessById(processId);
35 targetWindow = AutomationElement.FromHandle(p.MainWindowHandle);
36 return targetWindow;
37 }
38 catch (Exception ex)
39 {
40 count++;
41 StringBuilder sb = new StringBuilder();
42 string message = sb.AppendLine(string.Format("Target window is not existing.try #{0}", count)).ToString();
43 if (count > 5)
44 {
45 throw new InvalidProgramException(message, ex);
46 }
47 else
48 {
49 return FindWindowByProcessId(processId);
50 }
51 }
52 }
53
54 /**//// <summary>
55 /// Get the automation element by automation Id.
56 /// </summary>
57 /// <param name="windowName">Window name</param>
58 /// <param name="automationId">Control automation Id</param>
59 /// <returns>Automatin element searched by automation Id</returns>
60 public static AutomationElement FindElementById(int processId, string automationId)
61 {
62 AutomationElement aeForm = FindWindowByProcessId(processId);
63 AutomationElement tarFindElement = aeForm.FindFirst(TreeScope.Descendants,
64 new PropertyCondition(AutomationElement.AutomationIdProperty, automationId));
65 return tarFindElement;
66 }
67
68 ValuePattern helper#region ValuePattern helper
69
70 /**//// <summary>
71 /// To get the ValuePattern
72 /// </summary>
73 /// <param name="element">Target element</param>
74 /// <returns>ValuePattern instance</returns>
75 public static ValuePattern GetValuePattern(AutomationElement element)
76 {
77 object currentPattern;
78 if (!element.TryGetCurrentPattern(ValuePattern.Pattern, out currentPattern))
79 {
80 throw new Exception(string.Format("Element with AutomationId '{0}' and Name '{1}' does not support the ValuePattern.",
81 element.Current.AutomationId, element.Current.Name));
82 }
83 return currentPattern as ValuePattern;
84 }
85
86 #endregion
87 }
88}
89
1using System;
2using System.Text;
3using System.Diagnostics;
4using System.Threading;
5using System.Windows.Automation;
6
7namespace UIATest
8{
9 class Program
10 {
11 static void Main(string[] args)
12 {
13 Process process = Process.Start(@"F:\CSharpDotNet\AutomationTest\ATP\WpfApp\bin\Debug\WpfApp.exe");
14 int processId = process.Id;
15 AutomationElement element = FindElementById(processId, "textBox1");
16 ValuePattern currentPattern = GetValuePattern(element);
17 Console.WriteLine("Is read only:'{0}', TextBox text is:'{1}'", currentPattern.Current.IsReadOnly, currentPattern.Current.Value);
18 currentPattern.SetValue("KadenKang");
19 Console.WriteLine("After using the SetValue, the TextBox value is '{0}'", currentPattern.Current.Value);
20
21 }
22
23 /**//// <summary>
24 /// Get the automation elemention of current form.
25 /// </summary>
26 /// <param name="processId">Process Id</param>
27 /// <returns>Target element</returns>
28 public static AutomationElement FindWindowByProcessId(int processId)
29 {
30 AutomationElement targetWindow = null;
31 int count = 0;
32 try
33 {
34 Process p = Process.GetProcessById(processId);
35 targetWindow = AutomationElement.FromHandle(p.MainWindowHandle);
36 return targetWindow;
37 }
38 catch (Exception ex)
39 {
40 count++;
41 StringBuilder sb = new StringBuilder();
42 string message = sb.AppendLine(string.Format("Target window is not existing.try #{0}", count)).ToString();
43 if (count > 5)
44 {
45 throw new InvalidProgramException(message, ex);
46 }
47 else
48 {
49 return FindWindowByProcessId(processId);
50 }
51 }
52 }
53
54 /**//// <summary>
55 /// Get the automation element by automation Id.
56 /// </summary>
57 /// <param name="windowName">Window name</param>
58 /// <param name="automationId">Control automation Id</param>
59 /// <returns>Automatin element searched by automation Id</returns>
60 public static AutomationElement FindElementById(int processId, string automationId)
61 {
62 AutomationElement aeForm = FindWindowByProcessId(processId);
63 AutomationElement tarFindElement = aeForm.FindFirst(TreeScope.Descendants,
64 new PropertyCondition(AutomationElement.AutomationIdProperty, automationId));
65 return tarFindElement;
66 }
67
68 ValuePattern helper#region ValuePattern helper
69
70 /**//// <summary>
71 /// To get the ValuePattern
72 /// </summary>
73 /// <param name="element">Target element</param>
74 /// <returns>ValuePattern instance</returns>
75 public static ValuePattern GetValuePattern(AutomationElement element)
76 {
77 object currentPattern;
78 if (!element.TryGetCurrentPattern(ValuePattern.Pattern, out currentPattern))
79 {
80 throw new Exception(string.Format("Element with AutomationId '{0}' and Name '{1}' does not support the ValuePattern.",
81 element.Current.AutomationId, element.Current.Name));
82 }
83 return currentPattern as ValuePattern;
84 }
85
86 #endregion
87 }
88}
89
下面的代码是xaml设计:
Code
1<Window x:Class="WpfApp.Window1"
2 xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
3 xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
4 Title="Window1" Height="219" Width="353">
5 <Grid>
6 <TextBox Height="23" Margin="50,20,160,0" Name="textBox1" VerticalAlignment="Top" MaxLength="5">textBox text</TextBox>
7 </Grid>
8</Window>
9
1<Window x:Class="WpfApp.Window1"
2 xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
3 xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
4 Title="Window1" Height="219" Width="353">
5 <Grid>
6 <TextBox Height="23" Margin="50,20,160,0" Name="textBox1" VerticalAlignment="Top" MaxLength="5">textBox text</TextBox>
7 </Grid>
8</Window>
9
本文通过简单的实例介绍了UI Automation中的ValuePattern及其使用方法。