以下是一個使用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\"}";
? ? // }
}
?