You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

.NET4 WinForm动态DataGridViewCheckBoxCell测试唯一标识方案咨询

问题描述

基于.NET4的WinForm表格布局应用中,通过代码动态创建DataGridViewCheckBoxCell并添加到DataGridView第三列,应用运行正常,但使用WinAppDriver编写测试用例时,无法找到可唯一识别这些动态CheckBoxCell的属性。不想通过索引定位(避免依赖位置),曾尝试设置isMarriedCell.AccessibilityObject.Name和Tag属性,均无法在测试中定位到元素,需提供可行方案。

相关代码

按钮点击事件代码

private void populateBtn_Click(object sender, EventArgs e)
{
    Person[] data = new Person[] {
        new Person { Name = "samman", Age = 32, IsMarried = false, },
        new Person { Name = "tom", Age = 32, IsMarried = false, },
        new Person { Name = "harreld", Age = 32, IsMarried = false, },
    };

    int idx = 0;
    foreach (Person p in data )
    {
        DataGridViewCheckBoxCell isMarriedCell = new DataGridViewCheckBoxCell();

        isMarriedCell.Value = p.IsMarried;

        dataGridView1.Rows.Add(p.Name, p.Age);
        dataGridView1[2, idx] = isMarriedCell;

        idx++;
    }
}

测试用例代码片段

[ClassInitialize]
public static void ClassInitialize(TestContext context) {
    // ... 初始化代码
    session.FindElementByAccessibilityId("populateBtn").Click();
    // 尝试定位元素失败的代码
}

尝试过的无效操作

  • 设置isMarriedCell.AccessibilityObject.Name = $"gridviewcheckbox-{idx}",无法通过Inspect工具看到该名称
  • 设置isMarriedCell.Tag = $"checkbox-{idx}",使用session.FindElementByTagName定位时报错“无法找到元素”

可行解决方案

方案1:自定义DataGridViewCheckBoxCell并重写辅助功能对象

创建自定义单元格类,通过重写辅助功能实例来设置可被WinAppDriver识别的唯一标识:

public class CustomCheckBoxCell : DataGridViewCheckBoxCell
{
    public string AutomationId { get; set; }

    protected override AccessibleObject CreateAccessibilityInstance()
    {
        return new CustomCheckBoxCellAccessibleObject(this);
    }

    private class CustomCheckBoxCellAccessibleObject : DataGridViewCellAccessibleObject
    {
        private readonly CustomCheckBoxCell _ownerCell;

        public CustomCheckBoxCellAccessibleObject(CustomCheckBoxCell ownerCell) : base(ownerCell)
        {
            _ownerCell = ownerCell;
        }

        public override string Name => _ownerCell.AutomationId;
    }
}

创建单元格时使用自定义类并绑定唯一标识:

foreach (Person p in data )
{
    CustomCheckBoxCell isMarriedCell = new CustomCheckBoxCell();
    isMarriedCell.Value = p.IsMarried;
    // 用人员名称作为唯一标识,确保不重复
    isMarriedCell.AutomationId = $"married-checkbox-{p.Name}";

    dataGridView1.Rows.Add(p.Name, p.Age);
    dataGridView1[2, idx] = isMarriedCell;

    idx++;
}

测试时通过名称定位:

// 定位samman对应的CheckBox
var sammanCheckBox = session.FindElementByName("married-checkbox-samman");
sammanCheckBox.Click();

方案2:通过行数据关联定位

先定位目标人员所在行,再获取该行的CheckBox,无需修改单元格类:

// 找到Name为samman的行
var sammanRow = session.FindElementByXPath($"//DataGridViewRow[./DataGridViewCell[@Name='samman']]");
// 获取该行第三列的CheckBox
var sammanCheckBox = sammanRow.FindElementByXPath("./DataGridViewCell[3]/CheckBox");
sammanCheckBox.Click();

方案3:利用CellFormatting事件设置辅助属性

通过表格的CellFormatting事件,反射修改单元格辅助对象的名称字段(适配.NET4的限制):

private void dataGridView1_CellFormatting(object sender, DataGridViewCellFormattingEventArgs e)
{
    if (e.ColumnIndex == 2 && e.RowIndex >= 0)
    {
        var cell = dataGridView1[e.ColumnIndex, e.RowIndex];
        if (cell is DataGridViewCheckBoxCell)
        {
            var personName = dataGridView1[0, e.RowIndex].Value.ToString();
            var accessibleObject = cell.AccessibilityObject;
            // 通过反射修改内部名称字段
            var nameField = accessibleObject.GetType().GetField("_name", BindingFlags.Instance | BindingFlags.NonPublic);
            nameField?.SetValue(accessibleObject, $"married-checkbox-{personName}");
        }
    }
}

测试时同样通过FindElementByName定位对应元素即可。


内容的提问来源于stack exchange,提问作者samman adhikari

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.01 23:25:28