rautomation 0.12.0 → 0.13.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (31) hide show
  1. checksums.yaml +4 -4
  2. data/Gemfile.lock +1 -1
  3. data/History.rdoc +11 -1
  4. data/VERSION +1 -1
  5. data/ext/UiaDll/RAutomation.UIA/Controls/Clicker.cs +5 -1
  6. data/ext/UiaDll/RAutomation.UIA/Controls/SelectList.cs +41 -1
  7. data/ext/UiaDll/RAutomation.UIA/Controls/TableControl.cs +37 -2
  8. data/ext/UiaDll/RAutomation.UIA/Extensions/Element.cs +48 -1
  9. data/ext/UiaDll/UiaDll/SelectListMethods.cpp +23 -0
  10. data/ext/UiaDll/UiaDll/StringHelper.cpp +5 -0
  11. data/ext/UiaDll/UiaDll/StringHelper.h +1 -0
  12. data/ext/UiaDll/UiaDll/TableMethods.cpp +23 -5
  13. data/ext/WindowsForms/WindowsForms/AboutBox.Designer.cs +31 -0
  14. data/ext/WindowsForms/WindowsForms/DataEntryForm.Designer.cs +13 -0
  15. data/ext/WindowsForms/WindowsForms/DataEntryForm.cs +5 -0
  16. data/ext/WindowsForms/WindowsForms/MainFormWindow.Designer.cs +32 -22
  17. data/ext/WindowsForms/WindowsForms/MainFormWindow.cs +30 -1
  18. data/lib/rautomation/adapter/ms_uia/select_list.rb +8 -8
  19. data/lib/rautomation/adapter/ms_uia/table.rb +12 -8
  20. data/lib/rautomation/adapter/ms_uia/uia_dll.rb +36 -4
  21. data/spec/adapter/ms_uia/button_spec.rb +2 -2
  22. data/spec/adapter/ms_uia/checkbox_spec.rb +2 -2
  23. data/spec/adapter/ms_uia/listbox_spec.rb +15 -17
  24. data/spec/adapter/ms_uia/radio_spec.rb +1 -1
  25. data/spec/adapter/ms_uia/select_list_spec.rb +67 -65
  26. data/spec/adapter/ms_uia/spinner_spec.rb +1 -1
  27. data/spec/adapter/ms_uia/tab_control_spec.rb +3 -3
  28. data/spec/adapter/ms_uia/table_spec.rb +35 -17
  29. data/spec/adapter/ms_uia/text_field_spec.rb +2 -2
  30. data/spec/adapter/ms_uia/window_spec.rb +1 -63
  31. metadata +2 -2
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 178133c72cc25827e3ce116041461d98735467f7
4
- data.tar.gz: 67c1b8edff6687922c7fb97a879af84e10c58107
3
+ metadata.gz: 5e50cb69e80b4659265b0edfc11904e064efee3b
4
+ data.tar.gz: 6ea9b5a0d4cfc8c2c43ddd995c7a0c8b07ccff7e
5
5
  SHA512:
6
- metadata.gz: 400deacbc79aa298a3d33dd0fc186d9ce6cf3c19af9a5cc5e5cf10e838d4b9b1048b1cd8fc7794feec56c07097111b81a7c4798d8d08bfa479dcf04393534ffc
7
- data.tar.gz: c4c2e66e9d4699eedf120aa1352a3111fc1b956ffd0a48f44dbf471c5e158d7fa7e4ecdbacfc8a81b8c815a0839a3ff3b065e9323cd29ec4101bdf4cbf3826de
6
+ metadata.gz: 6bbe2f8ed80c1dff85044ce04fba2e62fac3489045d4cadaf792322f70eac4a9f06e08a4d86e6ec0e3afabc9ac6559e166f75397976b1af1f3ed76874976e88f
7
+ data.tar.gz: 2400713a652d47652e93249c2a38dcd8e809f46a619ea986762bada8d561f13e2eed3dff293eb2fc84020654efdf728599492a431026a6729b97543bd545578f
data/Gemfile.lock CHANGED
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- rautomation (0.12.0)
4
+ rautomation (0.13.0)
5
5
  ffi
6
6
 
7
7
  GEM
data/History.rdoc CHANGED
@@ -1,4 +1,14 @@
1
- == 0.12.0
1
+ == 0.13.0
2
+
3
+ === MsUia adapter
4
+
5
+ * Added #select and #clear into SelectList::SelectListOption for multi-select support
6
+ * Removed SelectList#select and SelectList#set
7
+ * Added #select, #selected? and #clear to Table::Row for multi-select support
8
+ * Removed Table#select and Table#selected?
9
+ * Fixed an issue with selecting ListBox items that our outside of the viewable area
10
+
11
+ == 0.12.0 / 2013-09-05
2
12
 
3
13
  === MsUia adapter
4
14
 
data/VERSION CHANGED
@@ -1 +1 @@
1
- 0.12.0
1
+ 0.13.0
@@ -1,5 +1,7 @@
1
1
  using System;
2
2
  using System.Runtime.InteropServices;
3
+ using System.Threading;
4
+ using System.Windows;
3
5
  using System.Windows.Automation;
4
6
  using System.Windows.Forms;
5
7
  using RAutomation.UIA.Extensions;
@@ -49,9 +51,11 @@ namespace RAutomation.UIA.Controls
49
51
 
50
52
  public static void MouseClick(AutomationElement element)
51
53
  {
54
+ element.ScrollToIfPossible();
52
55
  element.SetFocus();
56
+
53
57
  var clickablePoint = element.GetClickablePoint();
54
- Cursor.Position = new System.Drawing.Point((int) clickablePoint.X, (int) clickablePoint.Y);
58
+ Cursor.Position = new System.Drawing.Point((int)clickablePoint.X, (int)clickablePoint.Y);
55
59
  mouse_event(MOUSEEVENTLF_LEFTDOWN, 0, 0, 0, 0);
56
60
  mouse_event(MOUSEEVENTLF_LEFTUP, 0, 0, 0, 0);
57
61
  }
@@ -1,5 +1,7 @@
1
1
  using System.Collections.Generic;
2
2
  using System.Linq;
3
+ using System.Threading;
4
+ using System.Windows;
3
5
  using System.Windows.Automation;
4
6
  using RAutomation.UIA.Extensions;
5
7
  using RAutomation.UIA.Properties;
@@ -49,7 +51,35 @@ namespace RAutomation.UIA.Controls
49
51
  }
50
52
  }
51
53
 
52
- private static void Select(AutomationElement element)
54
+ public string[] Selections
55
+ {
56
+ get { return SelectionPattern.GetSelection().Select(x => x.Current.Name).ToArray(); }
57
+ }
58
+
59
+ public void Remove(int index)
60
+ {
61
+ SelectionItems.ElementAt(index).AsSelectionItem().RemoveFromSelection();
62
+ }
63
+
64
+ public void Remove(string value)
65
+ {
66
+ SelectionNamed(value).RemoveFromSelection();
67
+ }
68
+
69
+ private void Select(AutomationElement element)
70
+ {
71
+ if (SelectionPattern.CanSelectMultiple)
72
+ MultipleSelect(element);
73
+ else
74
+ SingleSelect(element);
75
+ }
76
+
77
+ private static void MultipleSelect(AutomationElement element)
78
+ {
79
+ element.AsSelectionItem().AddToSelection();
80
+ }
81
+
82
+ private static void SingleSelect(AutomationElement element)
53
83
  {
54
84
  var selectionItem = element.AsSelectionItem();
55
85
 
@@ -63,6 +93,16 @@ namespace RAutomation.UIA.Controls
63
93
  selectionItem.Select();
64
94
  }
65
95
 
96
+ private SelectionPattern.SelectionPatternInformation SelectionPattern
97
+ {
98
+ get { return _element.As<SelectionPattern>(System.Windows.Automation.SelectionPattern.Pattern).Current; }
99
+ }
100
+
101
+ private SelectionItemPattern SelectionNamed(string value)
102
+ {
103
+ return SelectionItems.First(x => x.Current.Name == value).AsSelectionItem();
104
+ }
105
+
66
106
  private static bool IsSelected(AutomationElement element)
67
107
  {
68
108
  return element.AsSelectionItem().Current.IsSelected;
@@ -23,12 +23,27 @@ namespace RAutomation.UIA.Controls
23
23
  public int SelectedIndex
24
24
  {
25
25
  get { return SelectionItems.IndexOf(x => x.Current.IsSelected); }
26
- set { DataItems.ElementAt(value).AsSelectionItem().Select(); }
26
+ set { Select(value); }
27
+ }
28
+
29
+ public bool IsRowSelected(int dataItemIndex)
30
+ {
31
+ return DataItems.ElementAt(dataItemIndex).AsSelectionItem().Current.IsSelected;
32
+ }
33
+
34
+ public void Remove(int dataItemIndex)
35
+ {
36
+ DataItems.ElementAt(dataItemIndex).AsSelectionItem().RemoveFromSelection();
37
+ }
38
+
39
+ public void Remove(string dataItemValue)
40
+ {
41
+ DataItems.FirstOrDefault(x => x.Current.Name == dataItemValue).AsSelectionItem().RemoveFromSelection();
27
42
  }
28
43
 
29
44
  public string Value
30
45
  {
31
- set { SelectionElements.First(x => x.Current.Name == value).AsSelectionItem().Select(); }
46
+ set { Select(value); }
32
47
  }
33
48
 
34
49
  public bool Exists(int row, int column)
@@ -56,6 +71,26 @@ namespace RAutomation.UIA.Controls
56
71
  get { return TableOrListItems.Select(x => x.Current.Name).ToArray(); }
57
72
  }
58
73
 
74
+ private void Select(int value)
75
+ {
76
+ var selectionItem = DataItems.ElementAt(value).AsSelectionItem();
77
+
78
+ if (SelectionPattern.CanSelectMultiple)
79
+ selectionItem.AddToSelection();
80
+ else
81
+ selectionItem.Select();
82
+ }
83
+
84
+ private SelectionPattern.SelectionPatternInformation SelectionPattern
85
+ {
86
+ get { return _element.As<SelectionPattern>(SelectionPatternIdentifiers.Pattern).Current; }
87
+ }
88
+
89
+ private void Select(string value)
90
+ {
91
+ SelectionElements.First(x => x.Current.Name == value).AsSelectionItem().Select();
92
+ }
93
+
59
94
  private IEnumerable<SelectionItemPattern> SelectionItems
60
95
  {
61
96
  get { return SelectionElements.Select(x => x.As<SelectionItemPattern>(SelectionItemPattern.Pattern)); }
@@ -1,4 +1,6 @@
1
- using System.Windows;
1
+ using System;
2
+ using System.Threading;
3
+ using System.Windows;
2
4
  using System.Windows.Automation;
3
5
 
4
6
  namespace RAutomation.UIA.Extensions
@@ -101,6 +103,51 @@ namespace RAutomation.UIA.Extensions
101
103
  return (bool)automationElement.GetCurrentPropertyValue(AutomationElement.IsValuePatternAvailableProperty);
102
104
  }
103
105
 
106
+ public static bool CanScrollTo(this AutomationElement automationElement)
107
+ {
108
+ return (bool)automationElement.GetCurrentPropertyValue(AutomationElement.IsScrollItemPatternAvailableProperty);
109
+ }
110
+
111
+ public static ScrollItemPattern AsScrollItem(this AutomationElement automationElement)
112
+ {
113
+ return automationElement.As<ScrollItemPattern>(ScrollItemPatternIdentifiers.Pattern);
114
+ }
115
+
116
+ public static bool HasClickablePoint(this AutomationElement automationElement)
117
+ {
118
+ Point point;
119
+ return automationElement.TryGetClickablePoint(out point);
120
+ }
121
+
122
+ public static bool ScrollToIfPossible(this AutomationElement automationElement)
123
+ {
124
+ if (!automationElement.CanScrollTo())
125
+ {
126
+ return false;
127
+ }
128
+
129
+ if (!automationElement.HasClickablePoint())
130
+ {
131
+ automationElement.AsScrollItem().ScrollIntoView();
132
+ automationElement.WaitUntilClickable(3);
133
+ }
134
+
135
+ return true;
136
+ }
137
+
138
+ public static void WaitUntilClickable(this AutomationElement automationElement, int howManySeconds)
139
+ {
140
+ var then = DateTime.Now;
141
+ while (!automationElement.HasClickablePoint())
142
+ {
143
+ Thread.Sleep(1);
144
+ if ((DateTime.Now - then).Seconds > howManySeconds)
145
+ {
146
+ throw new Exception(string.Format("Waited for more than {0} seconds to be able to click this", howManySeconds));
147
+ }
148
+ }
149
+ }
150
+
104
151
  public static ValuePattern AsValuePattern(this AutomationElement automationElement)
105
152
  {
106
153
  return (ValuePattern)automationElement.GetCurrentPattern(ValuePattern.Pattern);
@@ -26,6 +26,11 @@ extern "C" {
26
26
  StringHelper::CopyToUnmanagedString(selectList->Selection, selection, selectionLength);
27
27
  }
28
28
 
29
+ __declspec ( dllexport ) int SelectList_Selections(const FindInformation& findInformation, const char* selections[]) {
30
+ auto selectList = gcnew SelectList(Locator::FindFor(findInformation));
31
+ return StringHelper::Copy(selectList->Selections, selections);
32
+ }
33
+
29
34
  __declspec ( dllexport ) bool SelectList_ValueAt(const FindInformation& findInformation, const int whichItem, char* comboValue, const int comboValueSize) {
30
35
  try {
31
36
  auto selectList = gcnew SelectList(Locator::FindFor(findInformation));
@@ -37,6 +42,24 @@ extern "C" {
37
42
  }
38
43
  }
39
44
 
45
+ __declspec ( dllexport ) void SelectList_RemoveIndex(const FindInformation& findInformation, const int whichItem, char* errorInfo, const int errorInfoLength) {
46
+ try {
47
+ auto selectList = gcnew SelectList(Locator::FindFor(findInformation));
48
+ selectList->Remove(whichItem);
49
+ } catch(Exception^ e) {
50
+ StringHelper::Write(e, errorInfo, errorInfoLength);
51
+ }
52
+ }
53
+
54
+ __declspec ( dllexport ) void SelectList_RemoveValue(const FindInformation& findInformation, const char* whichItem, char* errorInfo, const int errorInfoLength) {
55
+ try {
56
+ auto selectList = gcnew SelectList(Locator::FindFor(findInformation));
57
+ selectList->Remove(gcnew String(whichItem));
58
+ } catch(Exception^ e) {
59
+ StringHelper::Write(e, errorInfo, errorInfoLength);
60
+ }
61
+ }
62
+
40
63
  __declspec ( dllexport ) bool SelectList_SelectIndex(const FindInformation& findInformation, const int whichItem) {
41
64
  try {
42
65
  auto selectList = gcnew SelectList(Locator::FindFor(findInformation));
@@ -8,6 +8,11 @@ void StringHelper::CopyToUnmanagedString(String^ source, char* destination, cons
8
8
  Marshal::FreeHGlobal(unmanagedString);
9
9
  }
10
10
 
11
+ void StringHelper::Write(Exception^ error, char* destination, const int destinationSize)
12
+ {
13
+ StringHelper::CopyToUnmanagedString(error->Message, destination, destinationSize);
14
+ }
15
+
11
16
  char* StringHelper::UnmanagedStringFrom(String^ source)
12
17
  {
13
18
  const int numberOfBytes = source->Length + 1;
@@ -5,6 +5,7 @@ ref class StringHelper
5
5
  {
6
6
  public:
7
7
  static void CopyToUnmanagedString(String^ source, char* destination, const int destinationSize);
8
+ static void StringHelper::Write(Exception^ error, char* destination, const int destinationSize);
8
9
  static char* UnmanagedStringFrom(String^ source);
9
10
  static void FreeUp(const char* unmanagedStrings[], const int numberOfStrings);
10
11
  static int Copy(array<String^>^ strings, const char* unmanagedStrings[]);
@@ -45,31 +45,49 @@ extern "C" {
45
45
  }
46
46
  }
47
47
 
48
- __declspec ( dllexport ) void Table_SelectByIndex(const FindInformation& findInformation, const int dataItemIndex) {
48
+ __declspec ( dllexport ) void Table_SelectByIndex(const FindInformation& findInformation, const int dataItemIndex, char* errorInfo, const int errorInfoLength) {
49
49
  try {
50
50
  auto tableControl = gcnew TableControl(Locator::FindFor(findInformation));
51
51
  tableControl->SelectedIndex = dataItemIndex;
52
52
  } catch(Exception^ e) {
53
- Console::WriteLine(e->ToString());
53
+ StringHelper::Write(e, errorInfo, errorInfoLength);
54
54
  }
55
55
  }
56
56
 
57
+ __declspec ( dllexport ) void Table_RemoveRowByIndex(const FindInformation& findInformation, const int dataItemIndex, char* errorInfo, const int errorInfoLength) {
58
+ try {
59
+ auto tableControl = gcnew TableControl(Locator::FindFor(findInformation));
60
+ tableControl->Remove(dataItemIndex);
61
+ } catch(Exception^ e) {
62
+ StringHelper::Write(e, errorInfo, errorInfoLength);
63
+ }
64
+ }
65
+
66
+ __declspec ( dllexport ) void Table_RemoveRowByValue(const FindInformation& findInformation, const char* dataItemValue, char* errorInfo, const int errorInfoLength) {
67
+ try {
68
+ auto tableControl = gcnew TableControl(Locator::FindFor(findInformation));
69
+ tableControl->Remove(gcnew String(dataItemValue));
70
+ } catch(Exception^ e) {
71
+ StringHelper::Write(e, errorInfo, errorInfoLength);
72
+ }
73
+ }
74
+
57
75
  __declspec ( dllexport ) bool Table_IsSelectedByIndex(const FindInformation& findInformation, const int dataItemIndex) {
58
76
  try {
59
77
  auto tableControl = gcnew TableControl(Locator::FindFor(findInformation));
60
- return tableControl->SelectedIndex == dataItemIndex;
78
+ return tableControl->IsRowSelected(dataItemIndex);
61
79
  } catch(Exception^ e) {
62
80
  Console::WriteLine(e->ToString());
63
81
  return false;
64
82
  }
65
83
  }
66
84
 
67
- __declspec ( dllexport ) void Table_SelectByValue(const FindInformation& findInformation, const char* dataItemValue) {
85
+ __declspec ( dllexport ) void Table_SelectByValue(const FindInformation& findInformation, const char* dataItemValue, char* errorInfo, const int errorInfoLength) {
68
86
  try {
69
87
  auto tableControl = gcnew TableControl(Locator::FindFor(findInformation));
70
88
  tableControl->Value = gcnew String(dataItemValue);
71
89
  } catch(Exception^ e) {
72
- Console::WriteLine(e->ToString());
90
+ StringHelper::Write(e, errorInfo, errorInfoLength);
73
91
  }
74
92
  }
75
93
  }
@@ -34,9 +34,12 @@
34
34
  this.infoTab = new System.Windows.Forms.TabPage();
35
35
  this.moreInfo = new System.Windows.Forms.TabPage();
36
36
  this.textBox1 = new System.Windows.Forms.TextBox();
37
+ this.tabPage1 = new System.Windows.Forms.TabPage();
38
+ this.multiFruitListBox = new System.Windows.Forms.ListBox();
37
39
  this.tabControl.SuspendLayout();
38
40
  this.infoTab.SuspendLayout();
39
41
  this.moreInfo.SuspendLayout();
42
+ this.tabPage1.SuspendLayout();
40
43
  this.SuspendLayout();
41
44
  //
42
45
  // label1
@@ -62,6 +65,7 @@
62
65
  //
63
66
  this.tabControl.Controls.Add(this.infoTab);
64
67
  this.tabControl.Controls.Add(this.moreInfo);
68
+ this.tabControl.Controls.Add(this.tabPage1);
65
69
  this.tabControl.Location = new System.Drawing.Point(12, 12);
66
70
  this.tabControl.Name = "tabControl";
67
71
  this.tabControl.SelectedIndex = 0;
@@ -99,6 +103,30 @@
99
103
  this.textBox1.TabIndex = 0;
100
104
  this.textBox1.Text = resources.GetString("textBox1.Text");
101
105
  //
106
+ // tabPage1
107
+ //
108
+ this.tabPage1.Controls.Add(this.multiFruitListBox);
109
+ this.tabPage1.Location = new System.Drawing.Point(4, 22);
110
+ this.tabPage1.Name = "tabPage1";
111
+ this.tabPage1.Padding = new System.Windows.Forms.Padding(3);
112
+ this.tabPage1.Size = new System.Drawing.Size(543, 227);
113
+ this.tabPage1.TabIndex = 2;
114
+ this.tabPage1.Text = "Multi-Select ListBox";
115
+ this.tabPage1.UseVisualStyleBackColor = true;
116
+ //
117
+ // multiFruitListBox
118
+ //
119
+ this.multiFruitListBox.FormattingEnabled = true;
120
+ this.multiFruitListBox.Items.AddRange(new object[] {
121
+ "Apple",
122
+ "Orange",
123
+ "Mango"});
124
+ this.multiFruitListBox.Location = new System.Drawing.Point(6, 6);
125
+ this.multiFruitListBox.Name = "multiFruitListBox";
126
+ this.multiFruitListBox.SelectionMode = System.Windows.Forms.SelectionMode.MultiExtended;
127
+ this.multiFruitListBox.Size = new System.Drawing.Size(159, 95);
128
+ this.multiFruitListBox.TabIndex = 15;
129
+ //
102
130
  // AboutBox
103
131
  //
104
132
  this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
@@ -120,6 +148,7 @@
120
148
  this.infoTab.PerformLayout();
121
149
  this.moreInfo.ResumeLayout(false);
122
150
  this.moreInfo.PerformLayout();
151
+ this.tabPage1.ResumeLayout(false);
123
152
  this.ResumeLayout(false);
124
153
 
125
154
  }
@@ -132,6 +161,8 @@
132
161
  private System.Windows.Forms.TabPage infoTab;
133
162
  private System.Windows.Forms.TabPage moreInfo;
134
163
  private System.Windows.Forms.TextBox textBox1;
164
+ private System.Windows.Forms.TabPage tabPage1;
165
+ private System.Windows.Forms.ListBox multiFruitListBox;
135
166
 
136
167
  }
137
168
  }
@@ -47,6 +47,7 @@
47
47
  this.label1 = new System.Windows.Forms.Label();
48
48
  this.maskedTextBox2 = new System.Windows.Forms.MaskedTextBox();
49
49
  this.numericUpDown1 = new System.Windows.Forms.NumericUpDown();
50
+ this.toggleMultiSelect = new System.Windows.Forms.Button();
50
51
  this.groupBox3.SuspendLayout();
51
52
  ((System.ComponentModel.ISupportInitialize)(this.numericUpDown1)).BeginInit();
52
53
  this.SuspendLayout();
@@ -164,11 +165,22 @@
164
165
  this.numericUpDown1.Size = new System.Drawing.Size(120, 20);
165
166
  this.numericUpDown1.TabIndex = 15;
166
167
  //
168
+ // toggleMultiSelect
169
+ //
170
+ this.toggleMultiSelect.Location = new System.Drawing.Point(12, 41);
171
+ this.toggleMultiSelect.Name = "toggleMultiSelect";
172
+ this.toggleMultiSelect.Size = new System.Drawing.Size(95, 23);
173
+ this.toggleMultiSelect.TabIndex = 16;
174
+ this.toggleMultiSelect.Text = "Toggle Multi";
175
+ this.toggleMultiSelect.UseVisualStyleBackColor = true;
176
+ this.toggleMultiSelect.Click += new System.EventHandler(this.toggleMultiSelect_Click);
177
+ //
167
178
  // DataEntryForm
168
179
  //
169
180
  this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
170
181
  this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
171
182
  this.ClientSize = new System.Drawing.Size(724, 474);
183
+ this.Controls.Add(this.toggleMultiSelect);
172
184
  this.Controls.Add(this.numericUpDown1);
173
185
  this.Controls.Add(this.maskedTextBox2);
174
186
  this.Controls.Add(this.label1);
@@ -201,5 +213,6 @@
201
213
  private System.Windows.Forms.ColumnHeader columnState;
202
214
  private System.Windows.Forms.MaskedTextBox maskedTextBox2;
203
215
  private System.Windows.Forms.NumericUpDown numericUpDown1;
216
+ private System.Windows.Forms.Button toggleMultiSelect;
204
217
  }
205
218
  }