我们正在为内部使用开发一个WPF 4.0应用程序。
在一些客户端上,由于UI自动化,我们遇到了巨大的性能问题(这些客户端安装了诸如tablet服务笔、touch、.等软件)。
这是WPF 4.0的一个已知问题,例如,请参见:
我们已经能够在一台规格非常有限的机器上复制这个问题。在此机器上打开WPF窗口需要:
正如您所看到的,安装hotfix KB2484841是一个巨大的改进,但仍然不如没有安装ui自动化触发软件的情况下运行的那么快。
此外,我们对在客户端安装哪个软件没有太多的控制,因此很难为所有客户端推出此修补程序。
因此,是否可以“关闭”整个WPF应用程序的UI自动化?我知道这可以在每个用户控制的基础上完成,但是对于整个应用程序来说是可能的吗?
我尝试过这 post中提供的代码,但没有成功。
耽误您时间,实在对不起,
柯恩
发布于 2014-10-17 21:36:24
我们遇到了问题中提到的相同问题,其中UI自动化客户端正在影响我们的WPF应用程序的性能。
在尝试了所有的热点修复和解决方法之后,我们终于找到了一个解决方案。每个UI控件都有一个AutomationPeer对象,该对象公开当前控件及其子控件的属性。UI自动化客户端使用这些AutomationPeer对象来获取有关UI控件的信息。WPF中的大多数UI控件都有内置的自动化对等类,我们还可以创建一个自定义对等类。
下面是一个自定义自动化对等类。注意,在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文章。
发布于 2013-11-06 19:01:49
DevExpress控件也有同样的问题。这两种解决方案的代码对我们都没有帮助。我认为没有任何“开关”来禁用UI自动化。但是自从上一个版本以来,DevExpress就有神奇的DevExpress类,它可以做一些技巧。正如我所理解的,这个想法是(通过反射)清除引起问题的控件的AutomationEvents.Count属性。例如,他们在基本控件中调用此方法(来自MeasureOverride),或在每次自动对等程序创建时调用该方法。
如果您使用DevExpress,这个类可以成为项目的灵丹妙药。在我们的WPF 4.0项目中,我们完全可以避免UI自动化问题的副作用,客户真的很高兴。
发布于 2013-07-25 00:35:59
尝试一些货物邪教程序:
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);
}https://stackoverflow.com/questions/17297539
复制相似问题