使用WPF自动化框架时,如何避免Thread.Sleep?

时间:2010-11-05 12:37:11

标签: wpf automation ui-automation

我正在尝试使用WPF UI Automation而不使用虚假的thread.sleep语句。我想要做的是有一个函数Ge​​tElementById,它持续轮询直到控件可用(或发生超时)。问题是它似乎缓存了我的父元素的子控件。是否可以刷新儿童?或者有没有人有另一种方法?

public AutomationElement GetElementById(string id, int timeout)
{
    if (timeout <= 1000) throw new ArgumentException("Timeout must be greater than 1000", "timeout");

    AutomationElement element = null;

    int timer = 0;
    const int delay = 100;

    do
    {       
        element = MainWindow.FindFirst(TreeScope.Descendants, new PropertyCondition(AutomationElement.AutomationIdProperty, id));                
        Thread.Sleep(delay);
        timer += delay;
    } while (element == null && timer < timeout);

    if (element == null) throw new InvalidOperationException("Unable to find element with id: " + id);

    return element;
}

2 个答案:

答案 0 :(得分:0)

System.Windows.Forms.Application命名空间中提供的DoEvents函数用于在发生长时间运行的进程时更新UI。它不是WPF名称空间的成员。您可以通过在article中自己实现它或者导入System.Windows.Forms命名空间并调用Application.DoEvents来使用某些东西。这将允许您在进行轮询时继续进行其他处理。这是一个谨慎使用的功能。

答案 1 :(得分:0)

如果有一种比明智地使用Thread.Sleep更好的方法,我还没有找到它。

UIAutomation确实提供了Events,我猜你可以(以你的情况为例)监听选择TabItem时发生的事件,然后继续按Id查找项目。但我怀疑这种模式会对代码的整体可读性造成严重破坏。