You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

在C#中创建自定义UIAutomation属性的实现咨询

在C#中为UI Automation添加自定义属性的实现方案

好问题!在C#里实现UI Automation自定义属性不需要手动做托管到非托管的封送处理——.NET的UI Automation框架已经帮我们封装好了类型转换的细节,你只需要按照正确的步骤注册属性并处理请求即可。下面是具体的实现步骤:

1. 注册自定义UI Automation属性

首先你需要通过AutomationProperty.Register方法创建一个自定义属性,这个方法会自动帮你分配合法的属性ID(无需手动指定0x80000000及以上的数值),同时关联对应的类型。

比如我们注册几个不同类型的自定义属性示例:

// 注册字符串类型的自定义属性
public static readonly AutomationProperty CustomDocumentPathProperty = 
    AutomationProperty.Register(
        "CustomDocumentPath", 
        typeof(string), 
        typeof(YourPaneProvider), // 你的提供者类类型
        new AutomationPropertyMetadata(
            string.Empty, // 默认值
            AutomationPropertyOptions.None));

// 注册布尔类型的自定义属性
public static readonly AutomationProperty IsDocumentModifiedProperty = 
    AutomationProperty.Register(
        "IsDocumentModified", 
        typeof(bool), 
        typeof(YourPaneProvider),
        new AutomationPropertyMetadata(
            false, 
            AutomationPropertyOptions.None));

// 注册整数类型的自定义属性
public static readonly AutomationProperty DocumentRevisionProperty = 
    AutomationProperty.Register(
        "DocumentRevision", 
        typeof(int), 
        typeof(YourPaneProvider),
        new AutomationPropertyMetadata(
            0, 
            AutomationPropertyOptions.None));

这里的类型要和你提到的UIAutomationType一一对应:

  • bool → UIAutomationType_Bool
  • int → UIAutomationType_Int
  • string → UIAutomationType_String
  • double → UIAutomationType_Double
  • System.Windows.Point → UIAutomationType_Point
  • AutomationElement → UIAutomationType_Element

2. 在GetPropertyValue中处理自定义属性请求

接下来在你现有的GetPropertyValue方法中,添加对自定义属性ID的判断逻辑,返回对应的值即可:

public object GetPropertyValue(int propertyId)
{
    // 先处理系统属性(保留你原有的代码)
    if (propertyId == AutomationElementIdentifiers.NameProperty.Id)
    {
        return View.Document.FullName;
    }
    else if (propertyId == AutomationElementIdentifiers.ControlTypeProperty.Id)
    {
        return ControlType.Pane.Id;
    }
    else if (propertyId == AutomationElementIdentifiers.IsContentElementProperty.Id)
    {
        return true;
    }
    else if (propertyId == AutomationElementIdentifiers.IsControlElementProperty.Id)
    {
        return true;
    }
    else if (propertyId == AutomationElementIdentifiers.IsKeyboardFocusableProperty.Id)
    {
        return false;
    }

    // 处理自定义属性
    else if (propertyId == CustomDocumentPathProperty.Id)
    {
        return View.Document.FilePath; // 返回你的自定义字符串值
    }
    else if (propertyId == IsDocumentModifiedProperty.Id)
    {
        return View.Document.IsModified; // 返回布尔值
    }
    else if (propertyId == DocumentRevisionProperty.Id)
    {
        return View.Document.RevisionNumber; // 返回整数值
    }
    else
    {
        // 不支持的属性返回null
        return null;
    }
}

关键细节说明

  • 为什么不需要手动封送?.NET的IRawElementProviderFragment等接口是COM互操作的包装类,框架会自动将你返回的托管类型(如stringbool)转换为UIA需要的非托管类型(对应UIAutomationType_*),完全不需要你手动写封送代码。
  • 自定义属性的可见性:注册后的自定义属性会被Ranorex、Test Complete等工具识别,你可以通过工具的属性查看器或者脚本获取这些属性值。
  • 属性ID范围:如果你不想用AutomationProperty.Register,也可以手动指定ID,但必须使用0x80000000到0xFFFFFFFF之间的数值(系统属性使用0x00000000到0x7FFFFFFF),不过推荐用Register方法,避免ID冲突。

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

火山引擎 最新活动