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

为何部分AutomationPeer被密封?DataGridRowAutomationPeer派生问题求解

DataGridRowAutomationPeer被设计为密封类的核心原因
  • 规避自定义派生带来的兼容性问题:DataGridRowAutomationPeer和DataGrid的虚拟化、选中状态同步、行列索引计算等内部逻辑深度耦合,微软密封该类是为了避免开发者重写时破坏内置的自动化交互逻辑,导致屏幕阅读器、自动化测试工具出现不可预期的异常,这类问题排查成本极高,也会破坏WPF内置控件的行为一致性。
  • 性能优化:开启行虚拟化的DataGrid会高频生成、销毁DataGridRow实例,密封类可以让CLR在运行时跳过虚方法表查找,做更高效的方法调用优化,减少大数据量场景下滚动时的性能开销。
  • 保障API迭代灵活性:如果开放该类的继承,后续微软调整DataGrid内部实现时必须兼容第三方派生类的逻辑,会大幅限制内部重构空间,密封后可以保证所有环境下该Peer的行为完全统一,不会出现版本差异导致的自动化逻辑失效。
可直接落地的替代实现方案

不需要强行派生密封的DataGridRowAutomationPeer,以下几个方案都可以满足FlaUI读取自定义参数的测试需求,实现成本远低于自定义Row Peer:

  • 自定义Automation属性映射方案
    首先给DataGridRow定义普通附加属性存储你需要暴露的自定义测试参数,再重写DataGrid的OnCreateAutomationPeer方法返回自定义的DataGridAutomationPeer,重写其GetChildrenCore逻辑,遍历每个行对应的内置DataGridRowAutomationPeer,读取行上存储的自定义参数,写入提前注册好的自定义AutomationProperty即可。FlaUI侧可以直接通过元素的GetPropertyValue方法读取该自定义属性值,完全不需要修改行Peer的实现。
    核心代码参考:
    // 注册测试用自定义自动化属性
    public static class AutoTestProps
    {
        public static readonly AutomationProperty RowCustomParamProperty = AutomationProperty.Register(
            "RowCustomParam", typeof(string), typeof(AutoTestProps), new PropertyMetadata(default(string)));
    }
    
    // 自定义DataGrid自动化Peer
    public class TestFriendlyDataGridPeer : DataGridAutomationPeer
    {
        public TestFriendlyDataGridPeer(DataGrid owner) : base(owner) { }
    
        protected override List<AutomationPeer> GetChildrenCore()
        {
            var childPeers = base.GetChildrenCore();
            foreach (var peer in childPeers)
            {
                if (peer is DataGridRowAutomationPeer rowPeer)
                {
                    var rowInstance = (DataGridRow)rowPeer.Owner;
                    var customVal = rowInstance.GetValue(CustomRowProps.TestParamProperty);
                    rowPeer.SetValue(AutoTestProps.RowCustomParamProperty, customVal);
                }
            }
            return childPeers;
        }
    }
    
  • 低代码快速方案:AutomationId/Name透传
    如果你的自定义参数是简单值类型、短字符串,完全不需要自定义任何AutomationPeer。只需要在DataGridRow加载时,把自定义参数按照约定格式拼接在AutomationProperties.AutomationId或者AutomationProperties.Name属性里,比如将行的AutomationId设置为data_row_{Index}|custom={TestParam},FlaUI侧拿到行元素后,直接读取AutomationId或者Name属性,按约定格式拆分字符串就能拿到目标参数,整个实现只需要几行业务代码,没有任何自定义Peer的开发量。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.30 12:12:22