Json的应用实例——cad 二次开发c#

发布于:2025-03-22 ⋅ 阅读:(54) ⋅ 点赞:(0)

以下是一个使用AutoCAD C#.NET API实现你需求的示例代码,代码实现了提示用户选择一个实体,将一些字符串变量及其对应的值组成JSON格式数据存储到实体的扩展数据(XData)中,并在弹出窗口中显示该实体的所有扩展数据信息。

 

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using Autodesk.AutoCAD.ApplicationServices;
using Autodesk.AutoCAD.DatabaseServices;
using Autodesk.AutoCAD.EditorInput;
using Newtonsoft.Json; // 需要引入Newtonsoft.Json库

namespace AcadXDataExample
{
    public class AcadXDataSample
    {
        [Autodesk.AutoCAD.Runtime.CommandMethod("SetAndShowXData")]
        public void SetAndShowXData()
        {
            Document doc = Application.DocumentManager.MdiActiveDocument;
            Database db = doc.Database;
            Editor ed = doc.Editor;

            // 提示用户选择一个实体
            PromptEntityOptions promptEntityOptions = new PromptEntityOptions("\n请选择一个实体: ");
            PromptEntityResult promptEntityResult = ed.GetEntity(promptEntityOptions);
            if (promptEntityResult.Status != PromptStatus.OK)
            {
                return;
            }

            // 定义一些字符串变量和对应的值
            string key1 = "Name";
            string value1 = "SampleEntity";
            string key2 = "Description";
            string value2 = "This is a sample entity for testing XData";

            // 将键值对组成字典
            Dictionary<string, string> dataDict = new Dictionary<string, string>
            {
                { key1, value1 },
                { key2, value2 }
            };

            // 将字典转换为JSON字符串
            string jsonData = JsonConvert.SerializeObject(dataDict);

            // 将JSON字符串存储为扩展数据(XData)
            using (Transaction trans = db.TransactionManager.StartTransaction())
            {
                try
                {
                    Entity entity = trans.GetObject(promptEntityResult.ObjectId, OpenMode.ForWrite) as Entity;
                    if (entity != null)
                    {
                        // 创建扩展数据的头部
                        ResultBuffer rb = new ResultBuffer(
                            new TypedValue((int)DxfCode.ExtendedDataRegAppName, "MyXDataApp"),
                            new TypedValue((int)DxfCode.Text, jsonData)
                        );
                        entity.XData = rb;
                        trans.Commit();
                    }
                }
                catch (Exception ex)
                {
                    trans.Abort();
                    MessageBox.Show($"存储扩展数据时出错: {ex.Message}");
                }
            }

            // 读取并显示实体的扩展数据
            using (Transaction trans = db.TransactionManager.StartTransaction())
            {
                try
                {
                    Entity entity = trans.GetObject(promptEntityResult.ObjectId, OpenMode.ForRead) as Entity;
                    if (entity != null && entity.HasXData)
                    {
                        ResultBuffer xData = entity.XData;
                        StringBuilder sb = new StringBuilder();
                        sb.AppendLine("实体的扩展数据信息:");
                        foreach (TypedValue tv in xData)
                        {
                            sb.AppendLine($"类型码: {tv.TypeCode}, 值: {tv.Value}");
                        }
                        MessageBox.Show(sb.ToString());
                    }
                    trans.Commit();
                }
                catch (Exception ex)
                {
                    trans.Abort();
                    MessageBox.Show($"读取扩展数据时出错: {ex.Message}");
                }
            }
        }
    }
}
上面代码修改后版本:

 

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using Autodesk.AutoCAD.ApplicationServices;
using Autodesk.AutoCAD.DatabaseServices;
using Autodesk.AutoCAD.EditorInput;
using Newtonsoft.Json; // 需要引入Newtonsoft.Json库

namespace AcadXDataExample
{
    public class AcadXDataSample
    {
        [Autodesk.AutoCAD.Runtime.CommandMethod("SetAndShowXData")]
        public void SetAndShowXData()
        {
            Document doc = Application.DocumentManager.MdiActiveDocument;
            Database db = doc.Database;
            Editor ed = doc.Editor;

            // 提示用户选择一个实体
            PromptEntityOptions promptEntityOptions = new PromptEntityOptions("\n请选择一个实体: ");
            PromptEntityResult promptEntityResult = ed.GetEntity(promptEntityOptions);
            if (promptEntityResult.Status != PromptStatus.OK)
            {
                return;
            }

            // 定义一些字符串变量和对应的值
            string key1 = "Name";
            string value1 = "SampleEntity";
            string key2 = "Description";
            string value2 = "This is a sample entity for testing XData";

            // 将键值对存储为扩展数据(XData)
            using (Transaction trans = db.TransactionManager.StartTransaction())
            {
                try
                {
                    Entity entity = trans.GetObject(promptEntityResult.ObjectId, OpenMode.ForWrite) as Entity;
                    if (entity != null)
                    {
                        // 创建扩展数据的头部
                        ResultBuffer rb = new ResultBuffer(
                            new TypedValue((int)DxfCode.ExtendedDataRegAppName, "MyXDataApp")
                        );

                        // 为每个键值对添加一个条目
                        rb.Add(new TypedValue((int)DxfCode.Text, key1));
                        rb.Add(new TypedValue((int)DxfCode.Text, value1));
                        rb.Add(new TypedValue((int)DxfCode.Text, key2));
                        rb.Add(new TypedValue((int)DxfCode.Text, value2));

                        entity.XData = rb;
                        trans.Commit();
                    }
                }
                catch (Exception ex)
                {
                    trans.Abort();
                    MessageBox.Show($"存储扩展数据时出错: {ex.Message}");
                }
            }

            // 读取并显示实体的扩展数据
            using (Transaction trans = db.TransactionManager.StartTransaction())
            {
                try
                {
                    Entity entity = trans.GetObject(promptEntityResult.ObjectId, OpenMode.ForRead) as Entity;
                    if (entity != null && entity.HasXData)
                    {
                        ResultBuffer xData = entity.XData;
                        StringBuilder sb = new StringBuilder();
                        sb.AppendLine("实体的扩展数据信息:");
                        for (int i = 0; i < xData.Count; i += 2)
                        {
                            string key = xData[i].Value.ToString();
                            string value = xData[i + 1].Value.ToString();
                            sb.AppendLine($"键: {key}, 值: {value}");
                        }
                        MessageBox.Show(sb.ToString());
                    }
                    trans.Commit();
                }
                catch (Exception ex)
                {
                    trans.Abort();
                    MessageBox.Show($"读取扩展数据时出错: {ex.Message}");
                }
            }
        }
    }
}

原始代码特点及逻辑:

 

将键值对先组织成字典,然后通过 Newtonsoft.Json 库序列化为JSON字符串。

 

在扩展数据(XData)中存储时,只有两个 TypedValue ,一个是应用程序名称( MyXDataApp ),另一个是包含所有键值对信息的JSON字符串。

 

读取时直接遍历整个 ResultBuffer 显示类型码和值,对于JSON数据需要进一步解析才能获取具体键值对内容。

 

修改后代码特点及逻辑:

 

没有使用JSON序列化,而是直接将每个键值对分别以 TypedValue 的形式添加到 ResultBuffer 中,每个键值对占用两个 TypedValue (一个键,一个值)。

 

存储扩展数据时,先添加应用程序名称的 TypedValue ,然后依次添加各个键值对的 TypedValue 。

 

读取时,通过循环以步长为2的方式遍历 ResultBuffer ,每次取出两个 TypedValue 分别作为键和值进行显示。

 

总结:

 

- 修改后的代码不依赖 Newtonsoft.Json 库,直接以简单的键值对形式存储和读取扩展数据,逻辑相对更直接,对于简单的键值对存储和读取场景比较清晰易懂。

 

- 原始代码使用JSON格式存储,可以方便地存储更复杂的数据结构(如嵌套的对象、数组等),但在读取时如果需要解析具体内容会相对复杂一些。

 

所以,修改后的代码在功能上是正确的,实现了将键值对存储到实体扩展数据并读取显示的功能,只是与原始代码在数据处理方式上有差异,具体使用哪种方式可以根据实际需求(如是否需要处理复杂数据结构、是否方便解析等)来决定。

 

以下是一个完整的C#示例代码,展示了如何在CAD C#开发中使用JSON来表示和处理扩展数据。为了简化示例,我将不包括与特定CAD API的交互部分,因为这部分会依赖于你所使用的CAD系统和API。不过,我会展示如何解析和生成JSON数据,并假设你已经有方法从CAD对象中获取和设置扩展数据。

 

using System;
using Newtonsoft.Json;

// 定义一个类来映射JSON数据的结构
public class ExtendedData
{
    public string Name { get; set; }
    public string Description { get; set; }
    public string Creator { get; set; }
    public DateTime CreatedDate { get; set; }
}

class Program
{
    static void Main(string[] args)
    {
        // 示例JSON字符串
        string jsonString = "{\"name\":\"ExampleObject\",\"description\":\"This is an example object with extended data.\",\"creator\":\"John Doe\",\"createdDate\":\"2025-03-21T17:17:08\"}";

        // 解析JSON字符串为ExtendedData对象
        ExtendedData extendedData = JsonConvert.DeserializeObject<ExtendedData>(jsonString);

        // 输出解析后的数据
        Console.WriteLine("Parsed Extended Data:");
        Console.WriteLine($"Name: {extendedData.Name}");
        Console.WriteLine($"Description: {extendedData.Description}");
        Console.WriteLine($"Creator: {extendedData.Creator}");
        Console.WriteLine($"Created Date: {extendedData.CreatedDate}");

        // 假设这里有一个方法将ExtendedData对象转换为适合CAD API的格式并添加到CAD对象中
        // AddExtendedDataToCadObject(extendedData);

        // 假设从CAD对象中获取了扩展数据的字符串表示
        // 这里我们再次使用相同的jsonString作为示例
        string extendedDataJson = jsonString; // 实际上,这应该从CAD对象中获取

        // 解析从CAD对象中获取的JSON字符串为ExtendedData对象
        ExtendedData retrievedData = JsonConvert.DeserializeObject<ExtendedData>(extendedDataJson);

        // 输出再次解析后的数据
        Console.WriteLine("\nRetrieved Extended Data:");
        Console.WriteLine($"Name: {retrievedData.Name}");
        Console.WriteLine($"Description: {retrievedData.Description}");
        Console.WriteLine($"Creator: {retrievedData.Creator}");
        Console.WriteLine($"Created Date: {retrievedData.CreatedDate}");
    }

    // 假设这里有一个方法从CAD对象中获取扩展数据的字符串表示
    // static string GetExtendedDataFromCadObject()
    // {
    //     // 实现获取扩展数据的逻辑
    //     return "{\"name\":\"ExampleObject\",\"description\":\"This is an example object with extended data.\",\"creator\":\"John Doe\",\"createdDate\":\"2025-03-21T17:17:08\"}";
    // }
}