Подтвердить что ты не робот

Можно ли отключить автоматизацию UI для всего приложения WPF 4.0?

Мы разрабатываем приложение WPF 4.0 для внутреннего использования.
На некоторых клиентах мы сталкиваемся с большими проблемами производительности благодаря автоматизации пользовательского интерфейса (у этих клиентов есть программное обеспечение, установленное как ручка планшета, сенсорный,..).

Это известная проблема для WPF 4.0, см., Например:


Мы смогли воспроизвести эту проблему на машине с очень ограниченными характеристиками. Открытие окна WPF на этом компьютере:

  • 00:00:02 - без установленного программного обеспечения для автоматизации пользовательского интерфейса.
  • 00:01:41 - с установленным программным обеспечением для запуска автоматизации пользовательского интерфейса (RoboForm для этого теста)
  • 00:00:09 - с установленным программным обеспечением для запуска автоматизации пользовательского интерфейса и исправлено приложение KB2484841

Как вы можете видеть, установка исправления KB2484841 - это огромное улучшение, но все же не так быстро, как работа без установленного программного обеспечения для запуска автоматизации.
Кроме того, у нас нет большого контроля над тем, какое программное обеспечение нужно устанавливать на клиентах, поэтому сложно решить эту проблему для всех клиентов.


Следовательно, возможно ли "отключить" автоматизацию пользовательского интерфейса для всего приложения WPF? Я знаю, что это можно сделать на основе каждого пользователя, но возможно ли это для приложения в целом?

Я пробовал код, указанный в этой, но без успеха.


Спасибо за ваше время,
Koen

4b9b3361

Ответ 1

Мы затронули ту же проблему, о которой упоминалось в вопросе, где клиент автоматизации пользовательского интерфейса влиял на производительность нашего приложения WPF.

После всех горячих исправлений и обходных решений, наконец, мы нашли решение. Каждый элемент управления пользовательского интерфейса имеет объект AutomationPeer, который предоставляет свойства текущего элемента управления и его дочерних элементов управления. Клиент автоматизации пользовательского интерфейса использует эти объекты AutomationPeer для получения информации об элементах управления пользовательским интерфейсом. Для большинства элементов управления пользовательского интерфейса в 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);
    }

Теперь, когда клиент автоматизации пользовательского интерфейса пытается получить дочерние элементы управления главного окна, он возвращает пустой список и поэтому не может проходить через остальные элементы управления.

Подробнее см. статью MSDN.

Ответ 2

У нас была такая же проблема с элементами управления DevExpress. Ни обходной код не помогает нам. И я полагаю, что нет никакого "переключателя" для отключения UI Automation. Но поскольку в последних версиях DevExpress есть волшебный класс ClearAutomationEventsHelper, который делает некоторые трюки. Как я понял, идея состоит в том, чтобы очистить свойство AutomationEvents.Count(через Reflection) для элементов управления, которые вызывают проблему. Например, они вызывают этот метод в своих базовых элементах управления (из MeasureOverride) или каждый раз созданный одноранговый механизм автоматизации.

Если вы используете DevExpress, этот класс может быть серебряной пулей для вашего проекта. Мы полностью избегаем побочных эффектов проблем автоматизации пользовательского интерфейса в наших проектах WPF 4.0, и клиенты были действительно счастливы.

Ответ 3

Попробуйте какое-то программирование с грузом:

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);
  }

Ответ 5

Вы пробовали следующие вещи:

  • Код автоматизации запускается только в том случае, если в машине работают клиенты автоматизации (например, программа чтения с экрана, табуляция в планшетах и ​​т.д.). Таким образом, один из способов выйти из этой ситуации - закрыть любое из этих клиентских приложений автоматизации.

  • Если один из вариантов невозможен, то альтернативой является UIElementHelper.InvalidateAutomationAncestors будет занимать больше времени, только если дерево автоматизации для приложения является редким (происходит, если отключено дерево автоматизации здания с помощью настраиваемого однорангового окна автоматизации), а визуальное дерево плотный. Таким образом, другое решение отключает любой пользовательский код автоматизации и позволяет WPF создавать полное дерево автоматизации. Это должно ускорить работу UIElementHelper.InvalidateAutomationAncestors.

Это то, что я нашел относительно вашей проблемы, также они сказали, что они знают об этой проблеме и попытаются ее исправить.