多段线扩展数据的应用场景

在C# CAD二次开发中,多段线(Polyline)的扩展数据(XData)主要用于为实体附加自定义的、非图形化的信息,以实现数据关联、流程控制或信息追溯等高级功能。

其核心用途可归纳为下表:

用途类别 具体说明 典型应用场景
存储自定义属性 将业务相关的属性(如构件ID、材料、状态、成本等)直接绑定到图形实体上。 在BIM或工程管理系统中,为多段线代表的管线、边界等存储其工程属性。
实现对象关联 通过存储其他实体的句柄(Handle)或唯一标识,建立图形对象之间的逻辑关系。 一条多段线(如道路中心线)通过扩展数据关联到多个标注或地块实体。
记录过程信息 保存实体创建、修改过程中的元数据,如创建者、时间、版本号或审批状态。 在协同设计流程中,追踪多段线的设计变更历史。
控制程序行为 存储特定标记或参数,供二次开发程序在运行时读取,以决定对实体的处理方式。 标记一条多段线是否需要被后续的批量处理程序忽略或进行特殊计算。

###核心操作代码示例

扩展数据的操作围绕 SetXDataGetXData 方法,并使用 ResultBuffer 来组织数据。数据以"类型-值"对(TypedValue)的形式存储。

  1. 为多段线写入扩展数据

以下代码演示如何为一条选中的多段线附加一个字符串类型的构件编号和一个整型的状态码。

csharp 复制代码
using Autodesk.AutoCAD.ApplicationServices;
using Autodesk.AutoCAD.DatabaseServices;
using Autodesk.AutoCAD.EditorInput;
using Autodesk.AutoCAD.Runtime;
using System;

public class XDataDemo
{
    [CommandMethod("WritePolylineXData")]
    public void WritePolylineXData()
    {
        Document doc = Application.DocumentManager.MdiActiveDocument;
        Database db = doc.Database;
        Editor ed = doc.Editor;

        // 1. 选择一条多段线
        PromptEntityOptions opt = new PromptEntityOptions("
请选择一条多段线:");
        opt.SetRejectMessage("
请选择多段线!");
        opt.AddAllowedClass(typeof(Polyline), false);
        PromptEntityResult res = ed.GetEntity(opt);
        if (res.Status != PromptStatus.OK) return;

        using (Transaction tr = db.TransactionManager.StartTransaction())
        {
            // 2. 以写模式打开多段线对象 Polyline pl = tr.GetObject(res.ObjectId, OpenMode.ForWrite) as Polyline;
            if (pl == null) return;

            // 3. 创建扩展数据缓冲区 (ResultBuffer)
            // 约定:注册应用名称为"MY_APP"
            string regAppName = "MY_APP";
            // 确保应用程序名称已注册到数据库
            RegAppTable rat = tr.GetObject(db.RegAppTableId, OpenMode.ForRead) as RegAppTable;
            if (!rat.Has(regAppName))
            {
                rat.UpgradeOpen();
                RegAppTableRecord ratr = new RegAppTableRecord();
                ratr.Name = regAppName;
                rat.Add(ratr);
                tr.AddNewlyCreatedDBObject(ratr, true);
            }

            // 4. 构建扩展数据内容 // 第一个TypedValue必须是注册应用程序名称 (1001, "MY_APP")
            // 后续可跟多个自定义数据对 ResultBuffer rb = new ResultBuffer();
            rb.Add(new TypedValue((int)DxfCode.ExtendedDataRegAppName, regAppName)); // 应用名 rb.Add(new TypedValue((int)DxfCode.ExtendedDataAsciiString, "BEAM-2024-001")); // 构件编号 (1000)
            rb.Add(new TypedValue((int)DxfCode.ExtendedDataInteger16, 1)); // 状态码 (1070)

            // 5. 将扩展数据赋给多段线 pl.XData = rb;
            rb.Dispose(); // 释放ResultBuffer资源

            tr.Commit();
            ed.WriteMessage("
成功为多段线写入扩展数据。");
        }
    }
}
  1. 从多段线读取扩展数据

以下代码演示如何读取并解析已附加的扩展数据。

csharp 复制代码
[CommandMethod("ReadPolylineXData")]
public void ReadPolylineXData()
{
    Document doc = Application.DocumentManager.MdiActiveDocument;
    Database db = doc.Database;
    Editor ed = doc.Editor;

    PromptEntityOptions opt = new PromptEntityOptions("
请选择一条带扩展数据的多段线:");
    opt.SetRejectMessage("
请选择多段线!");
    opt.AddAllowedClass(typeof(Polyline), false);
    PromptEntityResult res = ed.GetEntity(opt);
    if (res.Status != PromptStatus.OK) return;

    using (Transaction tr = db.TransactionManager.StartTransaction())
    {
        Polyline pl = tr.GetObject(res.ObjectId, OpenMode.ForRead) as Polyline;
        if (pl == null) return;

        // 获取扩展数据
        ResultBuffer rb = pl.GetXDataForApplication("MY_APP");
        if (rb == null)
        {
            ed.WriteMessage("
该多段线未找到'MY_APP'相关的扩展数据。");
            return;
        }

        // 遍历并解析ResultBuffer中的TypedValue
        ed.WriteMessage("
--- 扩展数据内容 ---");
        foreach (TypedValue tv in rb)
        {
            // 根据DxfCode判断数据类型并输出
            switch (tv.TypeCode)
            {
                case (int)DxfCode.ExtendedDataRegAppName:
                    ed.WriteMessage($"
应用名称: {tv.Value}");
                    break;
                case (int)DxfCode.ExtendedDataAsciiString: // 1000
                    ed.WriteMessage($"
字符串数据: {tv.Value}");
                    break;
                case (int)DxfCode.ExtendedDataInteger16: // 1070
                    ed.WriteMessage($"
短整型数据: {tv.Value}");
                    break;
                // 可继续添加其他类型的处理,如1071(长整型)、1040(双精度浮点)等 default:
                    ed.WriteMessage($"
未知类型码[{tv.TypeCode}]: {tv.Value}");
                    break;
            }
        }
        rb.Dispose();
        tr.Commit();
    }
}

关键注意事项1. 注册应用程序名称 :在写入扩展数据前,必须确保其关联的应用程序名称(如 "MY_APP")已存在于当前图形的注册应用程序表(RegAppTable)中,否则数据可能无法正确关联或读取。

  1. 数据类型与DxfCode :扩展数据支持多种数据类型,每种类型对应一个特定的 DxfCode(如1000代表字符串,1070代表16位整数)。必须使用正确的代码,否则在读取时会产生错误或乱码。
  2. 性能与存储:扩展数据存储在DWG文件内部,大量或过大的扩展数据会增加文件体积。对于海量复杂属性,应考虑使用外部数据库关联实体句柄(Handle)的方案。
  3. 事务管理:所有涉及数据库对象(包括扩展数据操作)的代码都必须置于事务(Transaction)中,以确保数据的一致性和完整性。

参考来源

相关推荐
慧都小妮子2 小时前
C# 实现AI合同审查:从读取、风险标注到批量签发
ai·自然语言处理·c#·.net·办公自动化·ai合同审查·文档ai代理
李高钢6 小时前
C# WPF 的 Prism 框架入门:核心概念与一个完整示例
开发语言·c#·wpf
牛哇网络工作室17 小时前
UnityHDRP写实数字人全流程基础5—语音输入和语音识别
android·unity·c#·游戏引擎·aigc·语音识别·xcode
zlinear数据采集卡1 天前
数据采集卡从入门到精通(9):分辨率与精度——16位卡不等于1/65536的精度
开发语言·数据库·fpga开发·开源·c#
深澈Vincel1 天前
我用 C# + WebView2 做了一个针对“流氓软件”的“一键清理工具“:架构实践与踩坑记录
c#
zlinear数据采集卡1 天前
数据采集卡从入门到精通(7):流水线型ADC——级级接力,高速与高精的平衡术
开发语言·arm开发·嵌入式硬件·fpga开发·c#
kingwebo'sZone1 天前
C# 根据公式计算的方法
开发语言·c#
阿部多瑞 ABU1 天前
告别手工核图:基于 .NET + MuPDFCore 的 CAD 等轴测 PDF 材料表提取与新旧版本对比实战
后端·算法·ui·pdf·c#
条形码D1 天前
DRG综合管理分析系统-目前已经支持CHS-DRG3.0
c#·drg·3.0分组器·drg分组器·chs-drg3.0分组器