26

内部使用のための WPF 4.0 アプリケーションを開発しています。
一部のクライアントでは、UI の自動化が原因で大きなパフォーマンスの問題が発生しています (これらのクライアントには、タブレット サービス ペン、タッチなどのソフトウェアがインストールされています)。

これは WPF 4.0 の既知の問題です。たとえば、次を参照してください。


非常に限られたスペックのマシンでこの問題を再現することができました。このマシンで WPF ウィンドウを開くには、次の処理が必要です。

  • 00:00:02 - UI 自動化トリガー ソフトウェアがインストールされていない
  • 00:01:41 - UI 自動化トリガー ソフトウェアがインストールされている (このテストではロボフォーム)
  • 00:00:09 - UI 自動化トリガー ソフトウェアがインストールされ、ホットフィックス KB2484841 が適用された状態

ご覧のとおり、ホットフィックス KB2484841 をインストールすると大幅に改善されますが、UI Automation トリガー ソフトウェアをインストールせずに実行する場合ほど高速ではありません。
さらに、どのソフトウェアをクライアントにインストールするかについてはあまり制御できないため、この修正をすべてのクライアントに展開することは困難です。


したがって、WPF アプリケーション全体の UI オートメーションを「オフ」にすることは可能ですか? UserControl ごとに実行できることはわかっていますが、アプリ全体で実行できますか?

この投稿で提供されているコードを試しましたが、成功しませんでした。


時間をありがとう、
コーエン

4

5 に答える 5

17

UI オートメーション クライアントがアプリケーションのパフォーマンスに影響を与えていたという、質問で述べたのとまったく同じ問題に遭遇しましたWPF

すべての修正プログラムと回避策を試した後、最終的に解決策を見つけました。各 UI コントロールにはAutomationPeer、現在のコントロールとその子コントロールのプロパティを公開するオブジェクトがあります。UI オートメーション クライアントは、これらのAutomationPeerオブジェクトを使用して、UI コントロールに関する情報を取得します。ほとんどの UI コントロールにはオートメーション ピア クラスが組み込まれてWPFおり、カスタム ピア クラスを作成することもできます。

以下は、カスタム オートメーション ピア クラスです。このGetChildrenCoreメソッドでは、実際の子コントロールのリストではなく空のリストを返していることに注意してください。

public class CustomWindowAutomationPeer : FrameworkElementAutomationPeer
{
    public CustomWindowAutomationPeer(FrameworkElement owner) : base(owner) { }

    protected override string GetNameCore()
    {
        return "CustomWindowAutomationPeer";
    }

    protected override AutomationControlType GetAutomationControlTypeCore()
    {
        return AutomationControlType.Window;
    }

    protected override List<AutomationPeer> GetChildrenCore()
    {
        return new List<AutomationPeer>();
    }
}

OnCreateAutomationPeer次に、メイン ウィンドウでメソッドをオーバーライドします。

protected override System.Windows.Automation.Peers.AutomationPeer OnCreateAutomationPeer()
{
    return new CustomWindowAutomationPeer(this);
}

UI オートメーション クライアントがメイン ウィンドウの子コントロールを取得しようとすると、空のリストが返されるため、残りのコントロールを反復処理できません。

詳細については、このMSDN の記事を参照してください。

于 2014-10-17T21:36:24.250 に答える
3

DevExpressコントロールでも同じ問題がありました。どちらの回避策コードも役に立ちません。また、UI オートメーションを無効にする「スイッチ」はないと思います。しかし、最後のバージョン以降、DevExpress にはいくつかのトリックを実行する魔法のClearAutomationEventsHelperクラスがあります。私が理解したように、アイデアは、問題を引き起こすコントロールの AutomationEvents.Count プロパティを (Reflection 経由で) クリアすることです。たとえば、ベース コントロールで (MeasureOverride から)、またはオートメーション ピアが作成されるたびに、このメソッドを呼び出します。

DevExpress を使用する場合、このクラスはプロジェクトの特効薬になる可能性があります。WPF 4.0 プロジェクトでの UI オートメーションの問題の副作用を完全に回避することができ、顧客は本当に満足しています。

于 2013-11-06T19:01:49.543 に答える
1

カーゴ・カルト・プログラミングを試してみてください:

WindowInteropHelper helper = new WindowInteropHelper(mainWindow);
        AutomationElement mainWindowAutomationElement = AutomationElement.FromHandle(helper.Handle);
        Automation.Automation.AddStructureChangedEventHandler(mainWindowAutomationElement, TreeScope.Descendants, AutomationFix);

      void AutomationFix(object sender, StructureChangedEventArgs e)
  {
            AutomationElement element = sender as AutomationElement;
    Automation.Condition condition = new PropertyCondition(AutomationElement.NameProperty, "!!");
    AutomationElement automationElement = element.FindFirst(TreeScope.Children, condition);
  }
于 2013-07-25T00:35:59.230 に答える
-1

次のことを試しましたか。

  1. 自動化コードは、自動化クライアント (スクリーン リーダー、タブレット PC のタブチップなど) がマシンで実行されている場合にのみトリガーされます。したがって、この状況から抜け出す 1 つの方法は、それらのオートメーション クライアント アプリを閉じることです。

  2. 1 つが実行可能でない場合、代わりに、UIElementHelper.InvalidateAutomationAncestors は、アプリのオートメーション ツリーがまばらで (カスタム ウィンドウ オートメーション ピアを使用してオートメーション ツリーの構築を無効にした場合に発生)、ビジュアル ツリーが密集している場合にのみ、より長い時間がかかります。したがって、別の解決策は、カスタム自動化コードを無効にして、WPF が完全な自動化ツリーを構築できるようにすることです。これにより、UIElementHelper.InvalidateAutomationAncestors も高速化されるはずです。

これはあなたの問題に関して私が見つけたものです。また、彼らはこの問題を認識しており、修正しようとしていると述べました.

于 2013-07-05T09:03:21.430 に答える