CodedUI:为什么查找单元格如此缓慢?

5
我在一个Winform应用程序中使用了一个网格(ComponentOne的FlexGrid),并尝试通过单元格的列索引和值查找该网格中的一个单元格。
我编写了下面的扩展方法来循环遍历网格并找到该单元格。
我正在测试这个方法,对于一个具有6列和64行的网格,我的代码需要10分钟才能找到正确的单元格(位于最后一行)。
有没有什么方法可以加速我的算法?
注意:我还尝试将PlayBack.PlayBackSetting.SmartMatchOption设置为TopLevelWindow,但似乎没有改变任何东西...
谢谢!
    public static WinCell FindCellByColumnAndValue(this WinTable table, int colIndex, string strCellValue)
    {

        int count = table.GetChildren().Count;
        for (int rowIndex = 0; rowIndex < count; rowIndex++)
        {
            WinRow row = new WinRow(table);
            WinCell cell = new WinCell(row);
            row.SearchProperties.Add(WinRow.PropertyNames.RowIndex, rowIndex.ToString());
            cell.SearchProperties.Add(WinCell.PropertyNames.ColumnIndex, colIndex.ToString());

            cell.SearchProperties.Add(WinCell.PropertyNames.Value, strCellValue);
            if (cell.Exists)
                return cell;
        }

        return new WinCell();
    }

编辑

我修改了我的方法,如下所示(例如,我不再使用winrow),这似乎快了约3倍。但是,在一个有3行6列的表格中查找单元格仍需要7秒钟,因此仍然相当慢...

我稍后会将此答案标记为已接受,以便给其他人留出时间提出更好的建议。

    public static WinCell FindCellByColumnAndValue(this WinTable table, int colIndex, string strCellValue, bool searchHeader = false)
    {
        Playback.PlaybackSettings.SmartMatchOptions = Microsoft.VisualStudio.TestTools.UITest.Extension.SmartMatchOptions.None;   
        int count = table.GetChildren().Count;
        for (int rowIndex = 0; rowIndex < count; rowIndex++)
        {
            WinCell cell = new WinCell(table);

            cell.SearchProperties.Add(WinRow.PropertyNames.RowIndex, rowIndex.ToString());
            cell.SearchProperties.Add(WinCell.PropertyNames.ColumnIndex, colIndex.ToString());


            cell.SearchProperties.Add(WinCell.PropertyNames.Value, strCellValue);
            if (cell.Exists)
                return cell;
        }

        return new WinCell();
    }

编辑 #2: 根据@Andrii的建议,我尝试使用FindMatchingControls,现在已经接近成功,只是在下面的代码中,单元格的列索引(c.ColumnIndex)有错误的值..

    public static WinCell FindCellByColumnAndValue2(this WinTable table, int colIndex, string strCellValue, bool searchHeader = false)
    {

        WinRow row = new WinRow(table);
        //Filter rows containing the wanted value
        row.SearchProperties.Add(new PropertyExpression(WinRow.PropertyNames.Value, strCellValue, PropertyExpressionOperator.Contains));
        var rows = row.FindMatchingControls();
        foreach (var r in rows)
        {
            WinCell cell = new WinCell(r);
            cell.SearchProperties.Add(WinCell.PropertyNames.Value, strCellValue);
            //Filter cells with the wanted value in the current row
            var controls = cell.FindMatchingControls();
            foreach (var ctl in controls)
            {
                var c = ctl as WinCell;
                if (c.ColumnIndex == colIndex)//ERROR: The only cell in my table with the correct value returns a column index of 2, instead of 0 (being in the first cell)
                    return c;
            }
        }
        return new WinCell();
    }

我认为在 MSDN 论坛的 UI 自动化测试 部分,他们通常会为 Coded UI 相关问题提供相当详细的答案。 - Andrii Kalytiiuk
@leppie:是的,我已经在他们的论坛上发布了一条消息,现在正在等待回复。 - David
@Andrii:我会去试试,谢谢。 - David
1个回答

6
我建议直接循环遍历子控件-根据我的经验,在Coded UI中使用复杂的搜索条件查找控件通常会变慢。 编辑: 为了提高性能,最好删除表格的子项并循环遍历行。另外,为了避免在没有行号的情况下找不到控件而引发异常,您可以使用FindMatchingControls方法,如下所示:
    public static WinCell FindCellByColumnAndValue(this WinTable table, int colIndex, string strCellValue, bool searchHeader = false)
    {
        Playback.PlaybackSettings.SmartMatchOptions = Microsoft.VisualStudio.TestTools.UITest.Extension.SmartMatchOptions.None;

        WinCell cell = new WinCell(table);
        cell.SearchProperties.Add(WinCell.PropertyNames.ColumnIndex, colIndex.ToString());
        cell.SearchProperties.Add(WinCell.PropertyNames.Value, strCellValue);

        UITestControlCollection foundControls = cell.FindMatchingControls();
        if (foundControls.Count > 0)
        {
            cell = foundControls.List[0];
        }
        else
        {
            cell = null;
        }

        return cell;
    }

当直接在表格中搜索表字段时,这将节省计算表中子控件的时间。同时,不使用for循环进行搜索会节省每次迭代行号时搜索字段的时间。
由于行号已遍历扩展中所有可用值,因此从长远来看,它不是必要的搜索标准。同时,对每个行号值进行迭代会引发额外的控件搜索请求,最终将方法的执行时间乘以网格中的行数。

如果你是指使用 table.GetChildren(),那样对我来说速度更慢了 :( - David
1
是的,我已经尝试过了,但是我遇到了以下错误System.ArgumentException: 未指定行作为控件的搜索容器。要使用“ColumnIndex”搜索单元格控件,必须将行指定为容器元素或将“RowIndex”添加到单元格的搜索属性中。 参数名称:SearchProperties这就是为什么我仍然在使用行的原因。 - David
@David 你尝试过只使用行实例进行搜索,而不指定特定的行号吗? - Andrii Kalytiiuk
@David 看起来应该使用FindMatchingControls方法来查找没有行号的字段。 - Andrii Kalytiiuk
我使用FindMatchingControl的解决方案更新了我的原始帖子。正如我之前提到的,当通过ColumnIndex搜索单元格时,您需要指定一个行容器或行索引。 - David

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接