2

WPF アプリ (.NET 4) 用の自動化された UI テストがいくつかあります。これらのテストでは、UI オートメーションAPI を使用します。

AutomationElement.FindFirstを呼び出してターゲット要素を見つけ、それを操作します。

例 (疑似コード):

var nameEquals = new PropertyCondition(AutomationElement.NameProperty, "OurAppWindow");
var appWindow = DesktopWindow.FindFirst(TreeScope.Children, nameEquals);
// this succeeds

var idEquals = new PropertyCondition(AutomationElement.AutomationIdProperty, "ControlId");
var someItem = appWindow.FindFirst(TreeScope.Descendants, idEquals);
// this suceeds sometimes, and fails sometimes!

問題は、appWindow.FindFirst要素が存在する場合でも、時々失敗して null を返すことです。UI オートメーション ツリーを手動で移動して出力するヘルパー関数を作成しました。正しい ID を持つ要素はすべての場合に存在します。

ウィンドウに他のアイテムがいくつ表示されているかに関係しているようです。他にアイテムがない場合は常に成功しますが、他の多くの複雑な UI 要素が横に表示されている場合、検索は失敗します。

ある種の内部要素制限に達しているように見えます。自動化 API のいずれかについて言及されている文書化された要素の制限が見つかりません。これを回避する方法はありますか? FindFirstツリー ウォーク自体を手動で実行する独自の実装を作成する必要があるかもしれないと考えています。これは不必要で遅いようです:-(

どんな助けでも大歓迎です

4

3 に答える 3

2

自動化していたアプリケーションの 1 つで同じ問題が発生しました。AdornerLayer にあるカスタム コントロールがあり、UI オートメーション ツリーを変更していたので、Adorner の AutomationElement は、アプリケーションのルートの子として表示されるのではなく、装飾しているコントロールの UI Visual 子として表示されました。

UI Spy を実行すると、出力ウィンドウに、ツリーをナビゲートしたときに無効な親に関するいくつかのエラーが表示されました。Adorner の AutomationElement の AutomationElement を親にする方法に関するコードのバグを解決しました。バグを修正すると、UI Spy は出力ウィンドウにエラーを表示しなくなり、FindFirst メソッド呼び出しからエラーが発生しなくなりました。

元の投稿者がまだこの質問を監視している場合、UI Spy でアプリケーションをナビゲートする際に問題はありますか?

于 2010-09-29T19:49:11.020 に答える
2

この問題を回避するには、ツリー ウォークを手動で行うのがおそらく最善の方法です。

FindFirst実際、ツリー ウォーキングを使用した実装はFindFirst、多数の子を持つ要素で使用するよりも高速であることがわかるでしょう。ReflectorのコードをAutomationElement.FindFirst見ると、条件に一致するすべての子を自動化境界を越えて引っ張ってから、最初の子を返すことによって機能することがわかります。対照的に、TreeWalker アプローチは、境界を越えて単一の最初の子を引っ張ろうとするだけです。

于 2010-06-09T08:39:52.650 に答える
-1

私もこの問題に固執しましたが、私は自分の失敗を見たことがありません。

var window = new System.Windows.Window();
window.Show();
window.Content = addControl;
GetWindow(window.Name);

その場でウィンドウを作成し、ウィンドウのコンテンツとしてコントロールを追加しました。ここでの私の失敗は、ウィンドウを表示してからコンテンツを割り当てたことです。これも失敗します。何時間も検索した後、コードを次のように変更しました。

var window = new System.Windows.Window();
window.Content = addControl;
window.Show();
GetWindow(window.Name);

...そしてそれは機能します。

マイケル

于 2011-01-06T13:23:38.583 に答える