TheSwamp
Code Red => .NET => Topic started by: teslaxx on December 15, 2010, 05:15:05 AM
-
My drawing has more than 2 layouts and in every layout, I have the same Mtext (same insert point).
How could I delete EVERY MText object from every layout?
My starting point is: http://docs.autodesk.com/ACD/2010/ENU/AutoCAD%20.NET%20Developer%27s%20Guide/index.html
1. I select the Mtext from Layout1
2. I call the Erase method from that entity
3. But How can I loop the rest of the layouts and delete the rest of the Mtexts, based on the characteristics of the selected Mtext?
[CommandMethod("SelectObjectsOnscreen")]
public static void SelectObjectsOnscreen()
{
// Get the current document and database
Document acDoc = Application.DocumentManager.MdiActiveDocument;
Database acCurDb = acDoc.Database;
// Start a transaction
using (Transaction acTrans = acCurDb.TransactionManager.StartTransaction())
{
// Request for objects to be selected in the drawing area
PromptSelectionResult acSSPrompt = acDoc.Editor.GetSelection();
// If the prompt status is OK, objects were selected
if (acSSPrompt.Status == PromptStatus.OK)
{
SelectionSet acSSet = acSSPrompt.Value;
// Step through the objects in the selection set
DBDictionary databaseDictionary = acCurDb.LayoutDictionaryId.GetObject(OpenMode.ForRead) as DBDictionary;
foreach (DBDictionaryEntry dictionaryEntry in databaseDictionary)
{
foreach (SelectedObject acSSObj in acSSet)
{
// Check to make sure a valid SelectedObject object was returned
if (acSSObj != null)
{
// Open the selected object for write
Entity acEnt = acTrans.GetObject(acSSObj.ObjectId,
OpenMode.ForWrite) as Entity;
//[color=red][b] Somehow I need to fetch the entities from the rest of the layouts, based on the entities selected from the first layout[/b][/color]
if (acEnt != null)
{
acEnt.Erase();
}
}
}
// Save the new object to the database
acTrans.Commit();
}
}
}
// Dispose of the transaction
}
-
My drawing has more than 2 layouts and in every layout, I have the same Mtext (same insert point).
How could I delete EVERY MText object from every layout?
1. I select the Mtext from Layout1
You might need GetEntity for that.
2. I call the Erase method from that entity
You might want to wait until your outer loop has finished.
3. But How can I loop the rest of the layouts and delete the rest of the Mtexts, based on the characteristics of the selected Mtext?
You might want to loop through the BlockTableRecords associated with the Layouts (see Layout.BlockTableRecordId property) and check for MTexts within your specification.
BTW:
// Open the selected object for write
Entity acEnt = acTrans.GetObject(acSSObj.ObjectId,
OpenMode.ForWrite) as Entity;
//[b] Somehow I need to fetch the entities from the rest of the layouts, based on the entities selected from the first layout[/b]
if (acEnt != null)
{
acEnt.Erase();
erases Entities, not MTexts. Try the 'as' keyword with the type MText, and if that checks != null, then it is really MTEXT.
Have fun.
-
Here is a start
Add ideas that Thorsten(kaefer) mentioned
Unless I am wrong I can not think of a situation where you would call Transaction.Commit() in a for each loop.
[CommandMethod("SelectObjectsOnscreen")]
public static void SelectObjectsOnscreen()
{
// Get the current document and database
Document acDoc = Application.DocumentManager.MdiActiveDocument;
Database acCurDb = acDoc.Database;
string txt = "";
Point3d mtxtInsertion = Point3d.Origin;
// Start a transaction
using (Transaction acTrans = acCurDb.TransactionManager.StartTransaction())
{
// Request for objects to be selected in the drawing area
PromptSelectionResult acSSPrompt = acDoc.Editor.GetSelection();
// If the prompt status is OK, objects were selected
if (acSSPrompt.Status == PromptStatus.OK)
{
SelectionSet acSSet = acSSPrompt.Value;
// Step through the objects in the selection set
DBDictionary databaseDictionary = acCurDb.LayoutDictionaryId.GetObject(OpenMode.ForRead) as DBDictionary;
foreach (SelectedObject acSSObj in acSSet)
{
// Check to make sure a valid SelectedObject object was returned
{
// Open the selected object for write
Entity acEnt = acTrans.GetObject(acSSObj.ObjectId,
OpenMode.ForWrite) as Entity;
//[b] Somehow I need to fetch the entities from the rest of the layouts, based on the entities selected from the first layout[/b]
if (acEnt is MText)
{
MText mtxt = acEnt as MText;
txt = mtxt.Contents;
mtxtInsertion = mtxt.Location;
acEnt.Erase();
}
}
}
foreach (DBDictionaryEntry dictionaryEntry in databaseDictionary)
{
Layout lyt = dictionaryEntry.Value.GetObject(OpenMode.ForRead) as Layout;
BlockTableRecord btr = lyt.BlockTableRecordId.GetObject(OpenMode.ForRead) as BlockTableRecord;
foreach (ObjectId objId in btr)
{
Entity ent = objId.GetObject(OpenMode.ForRead) as Entity;
if (ent is MText)
{
MText mtxt = ent as MText;
if (mtxt.Contents == txt && mtxt.Location == mtxtInsertion)
{
mtxt.UpgradeOpen();
mtxt.Erase();
}
}
}
}
// Save the new object to the database
acTrans.Commit();
}
}
// Dispose of the transaction
}
-
Thank you both!
P.S. For who he's trying to use the code of Jeff H, declare txt as string and mtxtInsertion as Point3d.
-
Unless I am wrong I can not think of a situation where you would call Transaction.Commit() in a for each loop.
Everytime you would call TransactionManager.StartTransaction() in a foreach loop? That happens not often, conceded; when going through the Databases of a DocumentCollection, perhaps.
Re: type conversions. I'd have thought the canonical way is (Type) when the target type is known, and the as operator for combined type test and conversion. Consequently, the is operator is seldom necessary.
Layout lyt = dictionaryEntry.Value.GetObject(OpenMode.ForRead) as Layout;
BlockTableRecord btr = lyt.BlockTableRecordId.GetObject(OpenMode.ForRead) as BlockTableRecord;
foreach (ObjectId objId in btr)
{
Entity ent = objId.GetObject(OpenMode.ForRead) as Entity;
if (ent is MText)
{
MText mtxt = ent as MText;
if (mtxt.Contents == txt && mtxt.Location == mtxtInsertion)
{
mtxt.UpgradeOpen();
mtxt.Erase();
}
}
}
should read
Layout lyt = (Layout)dictionaryEntry.Value.GetObject(OpenMode.ForRead);
BlockTableRecord btr = (BlockTableRecord)lyt.BlockTableRecordId.GetObject(OpenMode.ForRead);
foreach (ObjectId objId in btr)
{
MText mtxt = objId.GetObject(OpenMode.ForRead) as MText;
if (mtxt != null && mtxt.Contents == txt && mtxt.Location == mtxtInsertion)
{
mtxt.UpgradeOpen();
mtxt.Erase();
}
}
Regards
-
^^^
Here it is a great resource about some .NET little wonders...
http://geekswithblogs.net/BlackRabbitCoder/archive/2010/11/11/c.net-little-wonders---a-presentation.aspx
The As Cast it is on: C#/.NET Five Little Wonders (part 1)