我在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倍。它仍然需要7秒才能在一个包含3行和6列的表中找到一个单元格,所以它仍然很慢......
我会将此答案标记为后来接受,以便留出时间让其他人提出更好的建议
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();
}
答案 0 :(得分:6)
我建议通过子控件执行直接循环 - 根据我的经验,在Coded UI中搜索具有复杂搜索crieteria的控件经常运行缓慢。
修改强>
为了提高性能,最好删除计数表的子节点并循环遍历行。另外,为了避免在找到没有行号的控件时出现异常,可以使用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
循环的情况下进行搜索将为每次不匹配的行号迭代节省搜索字段的时间。
当行号遍历扩展中的所有可用值时 - 从长远来看,它不是必不可少的搜索条件。同时,每次迭代行号值都会调用额外的控制搜索请求 - 最终将方法的执行时间乘以网格中的行数。