0826xd
/// <summary>
/// 给任意实体增加扩展数据,写入原点坐标 (0,0,0)
/// </summary>
/// <typeparam name="T">实体类型 (如 Polyline, Line, Circle 等)</typeparam>
/// <param name="entity">目标实体</param>
/// <param name="appName">扩展数据应用名(默认 MyApp)</param>
public static void AddPtXData<T>(this T entity, Point3d pt,string appName = "MyApp") where T : Entity
{
if (entity == null) return;
Database db = entity.Database;
using (Transaction tr = db.TransactionManager.StartTransaction())
{
// 确保应用名已注册
RegAppTable rat = (RegAppTable)tr.GetObject(db.RegAppTableId, OpenMode.ForRead);
if (!rat.Has(appName))
{
rat.UpgradeOpen();
RegAppTableRecord ratr = new RegAppTableRecord { Name = appName };
rat.Add(ratr);
tr.AddNewlyCreatedDBObject(ratr, true);
}
// 构建扩展数据 (第一个必须是应用名)
ResultBuffer rb = new ResultBuffer(
new TypedValue((int)DxfCode.ExtendedDataRegAppName, appName),
new TypedValue((int)DxfCode.ExtendedDataXCoordinate, pt)
);
// 用事务重新获取实体 (写模式)
T entity2 = tr.GetObject(entity.ObjectId, OpenMode.ForWrite) as T;
if (entity2 == null) return;
// 读取旧的 XData
TypedValue[] oldValues = entity2.XData?.AsArray() ?? new TypedValue[0];
List<TypedValue> newValues = new List<TypedValue>(oldValues);
// 查找是否已有该 AppName
bool hasApp = false;
for (int i = 0; i < newValues.Count; i++)
{
if (newValues[i].TypeCode == (int)DxfCode.ExtendedDataRegAppName &&
(string)newValues[i].Value == appName)
{
hasApp = true;
// 在对应 appname 数据后追加坐标
newValues.Insert(i + 1, new TypedValue((int)DxfCode.ExtendedDataXCoordinate, pt));
break;
}
}
// 如果没有该 AppName,则新增一段
if (!hasApp)
{
newValues.Add(new TypedValue((int)DxfCode.ExtendedDataRegAppName, appName));
newValues.Add(new TypedValue((int)DxfCode.ExtendedDataXCoordinate, pt));
}
// 写入 XData
entity2.XData = new ResultBuffer(newValues.ToArray());
tr.Commit();
}
}
//public static void AddPtXData<T>(this T entity, Point3d pt, string appName = "MyApp", bool 追加 = false) where T : Entity
//{
// if (entity == null) return;
// Database db = entity.Database;
// using (Transaction tr = db.TransactionManager.StartTransaction())
// {
// // 确保应用名已注册
// RegAppTable rat = (RegAppTable)tr.GetObject(db.RegAppTableId, OpenMode.ForRead);
// if (!rat.Has(appName))
// {
// rat.UpgradeOpen();
// RegAppTableRecord ratr = new RegAppTableRecord { Name = appName };
// rat.Add(ratr);
// tr.AddNewlyCreatedDBObject(ratr, true);
// }
// // 用事务重新获取实体 (写模式)
// T entity2 = tr.GetObject(entity.ObjectId, OpenMode.ForWrite) as T;
// if (entity2 == null) return;
// // 读取旧的 XData
// TypedValue[] oldValues = entity2.XData?.AsArray() ?? new TypedValue[0];
// List<TypedValue> newValues = new List<TypedValue>(oldValues);
// // 查找是否已有该 AppName
// bool hasApp = false;
// int appIndex = -1;
// for (int i = 0; i < newValues.Count; i++)
// {
// if (newValues[i].TypeCode == (int)DxfCode.ExtendedDataRegAppName &&
// (string)newValues[i].Value == appName)
// {
// hasApp = true;
// appIndex = i;
// break;
// }
// }
// // 如果不需要追加,则先移除该应用名下的所有数据
// if (hasApp && !追加)
// {
// // 从应用名开始,移除所有属于该应用的扩展数据
// int index = appIndex;
// while (index < newValues.Count)
// {
// // 当遇到下一个应用名时停止移除
// if (index > appIndex && newValues[index].TypeCode == (int)DxfCode.ExtendedDataRegAppName)
// {
// break;
// }
// newValues.RemoveAt(index);
// }
// hasApp = false; // 标记为不存在,后续会添加新数据
// }
// // 处理数据添加
// if (hasApp)
// {
// // 追加模式:在对应 appname 数据后添加新坐标
// newValues.Insert(appIndex + 1, new TypedValue((int)DxfCode.ExtendedDataXCoordinate, pt));
// }
// else
// {
// // 新增或替换模式:添加应用名和新坐标
// newValues.Add(new TypedValue((int)DxfCode.ExtendedDataRegAppName, appName));
// newValues.Add(new TypedValue((int)DxfCode.ExtendedDataXCoordinate, pt));
// }
// // 写入 XData
// entity2.XData = new ResultBuffer(newValues.ToArray());
// tr.Commit();
// }
//}
public static void AddPtXData<T>(this T entity, Point3d pt, string appName = "MyApp", bool 追加 = false) where T : Entity
{
if (entity == null) return;
Database db = entity.Database;
using (Transaction tr = db.TransactionManager.StartTransaction())
{
// 确保应用名已注册
RegAppTable rat = (RegAppTable)tr.GetObject(db.RegAppTableId, OpenMode.ForRead);
if (!rat.Has(appName))
{
rat.UpgradeOpen();
RegAppTableRecord ratr = new RegAppTableRecord { Name = appName };
rat.Add(ratr);
tr.AddNewlyCreatedDBObject(ratr, true);
}
// 用事务重新获取实体 (写模式)
T entity2 = tr.GetObject(entity.ObjectId, OpenMode.ForWrite) as T;
if (entity2 == null) return;
// 读取旧的 XData
TypedValue[] oldValues = entity2.XData?.AsArray() ?? new TypedValue[0];
List<TypedValue> newValues = new List<TypedValue>(oldValues);
// 查找是否已有该 AppName
bool hasApp = false;
int appIndex = -1;
for (int i = 0; i < newValues.Count; i++)
{
if (newValues[i].TypeCode == (int)DxfCode.ExtendedDataRegAppName &&
(string)newValues[i].Value == appName)
{
hasApp = true;
appIndex = i;
break;
}
}
if (!hasApp)
{
// 新增或替换模式:添加应用名和新坐标
newValues.Add(new TypedValue((int)DxfCode.ExtendedDataRegAppName, appName));
newValues.Add(new TypedValue((int)DxfCode.ExtendedDataXCoordinate, pt));
}
// 如果不需要追加,则先移除该应用名下的所有数据
else
{
if ( !追加)
{
// 新增或替换模式:添加应用名和新坐标
newValues.Add(new TypedValue((int)DxfCode.ExtendedDataRegAppName, appName));
newValues.Add(new TypedValue((int)DxfCode.ExtendedDataXCoordinate, pt));
}
// 处理数据添加
else
{
// 追加模式:在对应 appname 数据后添加新坐标
newValues.Insert(appIndex + 1, new TypedValue((int)DxfCode.ExtendedDataXCoordinate, pt));
}
}
// 写入 XData
entity2.XData = new ResultBuffer(newValues.ToArray());
tr.Commit();
}
}
public static bool AddXDataToEntity(
ObjectId entityId,
string appName,
string baseValue,
int indexValue,
bool isAppend)
{
// 基础参数校验
if (string.IsNullOrEmpty(appName))
{
ShowMessage("应用名(appName)不能为空", Z.db);
return false;
}
if (entityId.IsNull)
{
ShowMessage("图元ID无效", Z.db);
return false;
}
if (Z.db == null)
{
//ShowMessage("数据库对象(Z.db)未初始化", null);
return false;
}
using (Transaction tr = Z.db.TransactionManager.StartTransaction())
{
try
{
// 1. 确保应用名已注册
RegAppTable regAppTable = tr.GetObject(Z.db.RegAppTableId, OpenMode.ForRead) as RegAppTable;
if (regAppTable == null)
{
ShowMessage("无法获取注册应用表(RegAppTable)", Z.db);
tr.Abort();
return false;
}
if (!regAppTable.Has(appName))
{
regAppTable.UpgradeOpen();
RegAppTableRecord regAppRecord = new RegAppTableRecord { Name = appName };
regAppTable.Add(regAppRecord);
tr.AddNewlyCreatedDBObject(regAppRecord, true);
// ShowMessage($"已注册新应用名:{appName}", Z.db);
}
// 2. 获取实体并升级为可写模式
Entity entity = tr.GetObject(entityId, OpenMode.ForRead) as Entity;
if (entity == null)
{
ShowMessage($"无法打开ID为{entityId}的图元", Z.db);
tr.Abort();
return false;
}
entity.UpgradeOpen();
// 3. 提取当前应用已有的XData(仅关注当前appName的数据)
List<TypedValue> currentAppExistingData = new List<TypedValue>(); // 当前应用的现有数据(包括标记)
bool isCurrentAppSection = false;
if (entity.XData != null)
{
foreach (TypedValue tv in entity.XData)
{
if (tv.TypeCode == (int)DxfCode.ExtendedDataRegAppName)
{
isCurrentAppSection = (tv.Value?.ToString() == appName);
if (isCurrentAppSection)
{
currentAppExistingData.Add(tv); // 保留当前应用标记
}
}
else if (isCurrentAppSection)
{
currentAppExistingData.Add(tv); // 保留当前应用的旧业务数据
}
// 忽略其他应用数据
}
}
// 4. 构建新的业务数据(待添加/追加的数据)
List<TypedValue> newBusinessData = new List<TypedValue>
{
new TypedValue((int)DxfCode.ExtendedDataAsciiString, baseValue),
new TypedValue((int)DxfCode.ExtendedDataInteger16, indexValue)
};
// 5. 构建最终XData
List<TypedValue> finalXData = new List<TypedValue>();
if (currentAppExistingData.Count == 0)
{
// 应用不存在:直接添加标记和新数据
ShowMessage($"应用名{appName}不存在,添加新数据", Z.db);
finalXData.Add(new TypedValue((int)DxfCode.ExtendedDataRegAppName, appName));
finalXData.AddRange(newBusinessData);
}
else if (isAppend)
{
// 追加操作:保留现有数据,仅在末尾插入新数据(不重复添加旧数据)
ShowMessage($"应用名{appName}存在,执行追加操作", Z.db);
finalXData.AddRange(currentAppExistingData); // 保留现有数据(标记+旧业务数据)
finalXData.AddRange(newBusinessData); // 仅插入新数据
}
else
{
// 覆盖操作:保留标记,替换为新数据
ShowMessage($"应用名{appName}存在,执行覆盖操作", Z.db);
finalXData.Add(currentAppExistingData[0]); // 保留标记
finalXData.AddRange(newBusinessData); // 覆盖为新数据
}
// 6. 写入最终XData
entity.XData = finalXData.Count > 0 ? new ResultBuffer(finalXData.ToArray()) : null;
tr.Commit();
// ShowMessage($"图元{entityId}的{appName}扩展数据处理成功", Z.db);
return true;
}
catch (Exception ex)
{
tr.Abort();
ShowMessage($"操作失败:{ex.Message}", Z.db);
return false;
}
}
}