更新图纸空间 autocad c# 中的属性
Update attributes in paperspace autocad c#
我正在尝试更新图纸空间中某些属性的值。该块及其属性可在多种布局中找到。我已经尝试了下面发布的代码,但我从 AttributeCollection 中得到了 NullReferenceException。该块被插入到图纸布置中。有人可以指出正确的方向如何解决这个问题或我做错了什么吗?提前致谢!
namespace InvullenKleinTitelhoek
{
public class Class2
{
[CommandMethod("KleineTitelhoekbis")]
public void UpdateBlockAttributes()
{
Document doc = Application.DocumentManager.MdiActiveDocument;
Database db = doc.Database;
Editor edt = doc.Editor;
//To change
//blockname TBM_DATA04_S_N
//att AT_DATA_DESC3_S_N
//att AT_DATA_DESC4_S_N"
//-----------------------------------------------------------------//
PromptStringOptions lijnDrie = new PromptStringOptions("Lijn 3");
lijnDrie.AllowSpaces = true;
PromptResult textStringLijnDrie = edt.GetString(lijnDrie);
string stLijnDrie = textStringLijnDrie.StringResult;
PromptStringOptions lijnVier = new PromptStringOptions("Lijn 4");
lijnVier.AllowSpaces = true;
PromptResult textStringLijnVier = edt.GetString(lijnVier);
string stLijnVier = textStringLijnVier.StringResult;
//-----------------------------------------------------------------//
using (Transaction trans = db.TransactionManager.StartTransaction())
{
try
{
DBDictionary layoutDict = trans.GetObject(db.LayoutDictionaryId, OpenMode.ForRead) as DBDictionary;
foreach(DBDictionaryEntry entry in layoutDict)
{
Layout ltr = (Layout)trans.GetObject((ObjectId)entry.Value, OpenMode.ForWrite);
BlockTable bt = trans.GetObject(db.BlockTableId, OpenMode.ForRead) as BlockTable;
BlockTableRecord btr = trans.GetObject(bt[BlockTableRecord.PaperSpace], OpenMode.ForRead) as BlockTableRecord;
foreach (ObjectId id in btr)
{
DBObject obj = trans.GetObject(id, OpenMode.ForRead);
BlockReference br = obj as BlockReference;
AttributeCollection attCol = br.AttributeCollection;
foreach (ObjectId objId in attCol)
{
DBObject dbobj = trans.GetObject(objId, OpenMode.ForRead) as DBObject;
AttributeReference attRef = dbobj as AttributeReference;
if (attRef.Tag == "AT_DATA_DESC3_S_N")
{
attRef.UpgradeOpen();
attRef.TextString = stLijnDrie;
}
if (attRef.Tag == "AT_DATA_DESC4_S_N")
{
attRef.UpgradeOpen();
attRef.TextString = stLijnVier;
}
}
}
trans.Commit();
}
}
catch (System.Exception ex)
{
edt.WriteMessage("error: " + ex.Message);
}
}
}
}
}
好问题
代码有一些错误
- 需要检查空属性集合
- 需要处理布局上有非块的对象的情况(转换为块将失败)
- 需要将 trans.Commit 语句移出所有循环
这是更新后的代码。
需要注意的一件事是,此代码只会在命令启动时更新当前活动的图纸空间选项卡上的块。
即使它遍历所有布局选项卡,它也不会更新所有布局。
public void UpdateBlockAttributes()
{
Document doc = Application.DocumentManager.MdiActiveDocument;
Database db = doc.Database;
Editor edt = doc.Editor;
PromptStringOptions lijnDrie = new PromptStringOptions("Lijn 3");
lijnDrie.AllowSpaces = true;
PromptResult textStringLijnDrie = edt.GetString(lijnDrie);
string stLijnDrie = textStringLijnDrie.StringResult;
PromptStringOptions lijnVier = new PromptStringOptions("Lijn 4");
lijnVier.AllowSpaces = true;
PromptResult textStringLijnVier = edt.GetString(lijnVier);
string stLijnVier = textStringLijnVier.StringResult;
// The document must be locked before making modifications
using (DocumentLock @lock = doc.LockDocument)
{
using (Transaction trans = db.TransactionManager.StartTransaction())
{
try
{
DBDictionary layoutDict = trans.GetObject(db.LayoutDictionaryId, OpenMode.ForWrite) as DBDictionary;
string originalLayout = LayoutManager.Current.CurrentLayout;
foreach (DBDictionaryEntry entry in layoutDict)
{
Layout ltr = (Layout)trans.GetObject((ObjectId)entry.Value, OpenMode.ForWrite);
string layoutName = ltr.LayoutName;
BlockTable bt = trans.GetObject(db.BlockTableId, OpenMode.ForWrite) as BlockTable;
BlockTableRecord btr = trans.GetObject(bt(BlockTableRecord.PaperSpace), OpenMode.ForWrite) as BlockTableRecord;
if (!layoutName.Equals("Model"))
{
// Set layout as current so code can modify block attributes on the layout
LayoutManager.Current.CurrentLayout = layoutName;
edt.WriteMessage("layout name: " + layoutName + Constants.vbLf);
foreach (ObjectId id in btr)
{
DBObject obj = trans.GetObject(id, OpenMode.ForWrite);
Entity entity = obj as Entity;
string ownerName = entity.BlockName;
BlockReference br = obj as BlockReference;
// If cast to block succeeded
if (br != null)
{
string blockName = br.Name;
AttributeCollection attCol = br.AttributeCollection;
edt.WriteMessage("block name: " + blockName + Constants.vbLf);
// If block has attributes
if (attCol != null & attCol.Count > 0)
{
foreach (ObjectId objId in attCol)
{
DBObject dbobj = trans.GetObject(objId, OpenMode.ForWrite) as DBObject;
AttributeReference attRef = dbobj as AttributeReference;
if (attRef.Tag == "AT_DATA_DESC3_S_N")
{
edt.WriteMessage("edited att value for: " + attRef.Tag + Constants.vbLf);
attRef.UpgradeOpen();
attRef.TextString = stLijnDrie;
}
if (attRef.Tag == "AT_DATA_DESC4_S_N")
{
edt.WriteMessage("edited att value for: " + attRef.Tag + Constants.vbLf);
attRef.UpgradeOpen();
attRef.TextString = stLijnVier;
}
}
}
}
}
}
}
LayoutManager.Current.CurrentLayout = originalLayout;
// Transaction needs to be outside of loop where code is doing modifications, otherwise it will be closed on commit
// causing error mesasge "Operation is not valid due to the current state of the object."
trans.Commit();
}
catch (Exception ex)
{
edt.WriteMessage("error: " + ex.Message + Constants.vbLf);
}
}
}
}
我正在尝试更新图纸空间中某些属性的值。该块及其属性可在多种布局中找到。我已经尝试了下面发布的代码,但我从 AttributeCollection 中得到了 NullReferenceException。该块被插入到图纸布置中。有人可以指出正确的方向如何解决这个问题或我做错了什么吗?提前致谢!
namespace InvullenKleinTitelhoek
{
public class Class2
{
[CommandMethod("KleineTitelhoekbis")]
public void UpdateBlockAttributes()
{
Document doc = Application.DocumentManager.MdiActiveDocument;
Database db = doc.Database;
Editor edt = doc.Editor;
//To change
//blockname TBM_DATA04_S_N
//att AT_DATA_DESC3_S_N
//att AT_DATA_DESC4_S_N"
//-----------------------------------------------------------------//
PromptStringOptions lijnDrie = new PromptStringOptions("Lijn 3");
lijnDrie.AllowSpaces = true;
PromptResult textStringLijnDrie = edt.GetString(lijnDrie);
string stLijnDrie = textStringLijnDrie.StringResult;
PromptStringOptions lijnVier = new PromptStringOptions("Lijn 4");
lijnVier.AllowSpaces = true;
PromptResult textStringLijnVier = edt.GetString(lijnVier);
string stLijnVier = textStringLijnVier.StringResult;
//-----------------------------------------------------------------//
using (Transaction trans = db.TransactionManager.StartTransaction())
{
try
{
DBDictionary layoutDict = trans.GetObject(db.LayoutDictionaryId, OpenMode.ForRead) as DBDictionary;
foreach(DBDictionaryEntry entry in layoutDict)
{
Layout ltr = (Layout)trans.GetObject((ObjectId)entry.Value, OpenMode.ForWrite);
BlockTable bt = trans.GetObject(db.BlockTableId, OpenMode.ForRead) as BlockTable;
BlockTableRecord btr = trans.GetObject(bt[BlockTableRecord.PaperSpace], OpenMode.ForRead) as BlockTableRecord;
foreach (ObjectId id in btr)
{
DBObject obj = trans.GetObject(id, OpenMode.ForRead);
BlockReference br = obj as BlockReference;
AttributeCollection attCol = br.AttributeCollection;
foreach (ObjectId objId in attCol)
{
DBObject dbobj = trans.GetObject(objId, OpenMode.ForRead) as DBObject;
AttributeReference attRef = dbobj as AttributeReference;
if (attRef.Tag == "AT_DATA_DESC3_S_N")
{
attRef.UpgradeOpen();
attRef.TextString = stLijnDrie;
}
if (attRef.Tag == "AT_DATA_DESC4_S_N")
{
attRef.UpgradeOpen();
attRef.TextString = stLijnVier;
}
}
}
trans.Commit();
}
}
catch (System.Exception ex)
{
edt.WriteMessage("error: " + ex.Message);
}
}
}
}
}
好问题
代码有一些错误
- 需要检查空属性集合
- 需要处理布局上有非块的对象的情况(转换为块将失败)
- 需要将 trans.Commit 语句移出所有循环
这是更新后的代码。
需要注意的一件事是,此代码只会在命令启动时更新当前活动的图纸空间选项卡上的块。
即使它遍历所有布局选项卡,它也不会更新所有布局。
public void UpdateBlockAttributes()
{
Document doc = Application.DocumentManager.MdiActiveDocument;
Database db = doc.Database;
Editor edt = doc.Editor;
PromptStringOptions lijnDrie = new PromptStringOptions("Lijn 3");
lijnDrie.AllowSpaces = true;
PromptResult textStringLijnDrie = edt.GetString(lijnDrie);
string stLijnDrie = textStringLijnDrie.StringResult;
PromptStringOptions lijnVier = new PromptStringOptions("Lijn 4");
lijnVier.AllowSpaces = true;
PromptResult textStringLijnVier = edt.GetString(lijnVier);
string stLijnVier = textStringLijnVier.StringResult;
// The document must be locked before making modifications
using (DocumentLock @lock = doc.LockDocument)
{
using (Transaction trans = db.TransactionManager.StartTransaction())
{
try
{
DBDictionary layoutDict = trans.GetObject(db.LayoutDictionaryId, OpenMode.ForWrite) as DBDictionary;
string originalLayout = LayoutManager.Current.CurrentLayout;
foreach (DBDictionaryEntry entry in layoutDict)
{
Layout ltr = (Layout)trans.GetObject((ObjectId)entry.Value, OpenMode.ForWrite);
string layoutName = ltr.LayoutName;
BlockTable bt = trans.GetObject(db.BlockTableId, OpenMode.ForWrite) as BlockTable;
BlockTableRecord btr = trans.GetObject(bt(BlockTableRecord.PaperSpace), OpenMode.ForWrite) as BlockTableRecord;
if (!layoutName.Equals("Model"))
{
// Set layout as current so code can modify block attributes on the layout
LayoutManager.Current.CurrentLayout = layoutName;
edt.WriteMessage("layout name: " + layoutName + Constants.vbLf);
foreach (ObjectId id in btr)
{
DBObject obj = trans.GetObject(id, OpenMode.ForWrite);
Entity entity = obj as Entity;
string ownerName = entity.BlockName;
BlockReference br = obj as BlockReference;
// If cast to block succeeded
if (br != null)
{
string blockName = br.Name;
AttributeCollection attCol = br.AttributeCollection;
edt.WriteMessage("block name: " + blockName + Constants.vbLf);
// If block has attributes
if (attCol != null & attCol.Count > 0)
{
foreach (ObjectId objId in attCol)
{
DBObject dbobj = trans.GetObject(objId, OpenMode.ForWrite) as DBObject;
AttributeReference attRef = dbobj as AttributeReference;
if (attRef.Tag == "AT_DATA_DESC3_S_N")
{
edt.WriteMessage("edited att value for: " + attRef.Tag + Constants.vbLf);
attRef.UpgradeOpen();
attRef.TextString = stLijnDrie;
}
if (attRef.Tag == "AT_DATA_DESC4_S_N")
{
edt.WriteMessage("edited att value for: " + attRef.Tag + Constants.vbLf);
attRef.UpgradeOpen();
attRef.TextString = stLijnVier;
}
}
}
}
}
}
}
LayoutManager.Current.CurrentLayout = originalLayout;
// Transaction needs to be outside of loop where code is doing modifications, otherwise it will be closed on commit
// causing error mesasge "Operation is not valid due to the current state of the object."
trans.Commit();
}
catch (Exception ex)
{
edt.WriteMessage("error: " + ex.Message + Constants.vbLf);
}
}
}
}