Hi all,
I was writing code for my custom .net extension dll and one of the procedure involved therein was to replace the Text of MTEXT and DBTEXT entities with some predetermined Text String. I am using C#, AutoCAD 2012, and Visual Studio 2010. Here is the part of code wherein I am trying to replace the Text String of the MTEXT or DBTEXT entities.
foreach (SelectedObject selectedObject in selectionSet) { Entity currentEntity = transaction.GetObject(selectedObject.ObjectId, OpenMode.ForWrite, false) as Entity; if (currentEntity == null) { continue; } if (currentEntity.GetType() == typeof(MText)) { ((MText)currentEntity).Contents = textToCopy; } else { ((DBText)currentEntity).TextString = textToCopy; } } transaction.Commit();
The issue is that the text of the MTEXT or DBTEXT is not getting replaced with the string I am trying to. I debugged the code and it correctly hits the setting of MText.Contents == "Some String" and also transaction.commit(). But the text of the MTEXT still remains to the old value. Is this the correct way of changing the text of MTEXT / DBTEXT through the .Net API. If not, can someone guide me in any way please ?
regards,
Nirvan.
Hi Nirvan,
I tried your code and had no problem with it. Could there be something wrong with how your SelectionSet is being populated?
Below is the test command that I created based on your code. It changes the text for all DBText and MText entities in model space. And it worked perfectly for me in AutoCAD 2012 using VS 2010.
[CommandMethod("TestTextChange")] public static void TestTextChange() { Document doc = Application.DocumentManager.MdiActiveDocument; Database db = doc.Database; using (Transaction tr = db.TransactionManager.StartTransaction()) { BlockTableRecord btr = (BlockTableRecord)tr.GetObject (SymbolUtilityServices.GetBlockModelSpaceId(db), OpenMode.ForRead); foreach (ObjectId id in btr) { Entity currentEntity = tr.GetObject(id, OpenMode.ForWrite, false) as Entity; if (currentEntity == null) { continue; } if (currentEntity.GetType() == typeof(MText)) { ((MText)currentEntity).Contents = "BlahBlah"; } else { ((DBText)currentEntity).TextString = "BlahBlah"; } } tr.Commit(); } }
If you still have problems you might need to add some more code to help diagnose the source of your issue.
Art
One more thing... your else statement will be applied to any entity that is not an MText entity. Is that really what you want to do? What happens if it is a Circle? Then your cast will fail.
I would write your code this way:
foreach (SelectedObject selectedObject in selectionSet) { DBObject obj = transaction.GetObject(selectedObject.ObjectId, OpenMode.ForWrite); MText mtext = obj as MText; if (mtext != null) { mtext.Contents = "BlahBlah"; continue; } DBText text = obj as DBText; if (text != null) { text.TextString = "BlahBlah"; } } transaction.Commit();
ArtVegas,
Thanks for all the comments. Actually, I had nested transaction and the outer one was aborting. As a result, even though the inner one (as visible in my code in question) was commiting, the changes were not getting applied.
Even though TextEntity.Context = "abc.." does replace the text string, the formatting disappears as the Contents also contain formatting data. A better way that I found out on net was to use the TextEditor. I will provide a sample below to help someone looking for replacing the MText. Here is the part of relevant code.
if (currentEntity.GetType() == typeof(MText)) { TextEditor textEditor = TextEditor.CreateTextEditor((MText)currentEntity); textEditor.SelectAll(); TextEditorSelection selection = textEditor.Selection; selection.InsertString(replaceText); textEditor.Close(TextEditor.ExitStatus.ExitSave); }
regards,
Nirvan.
Hello,
I am new in Autocad API. I am interested in this topic. I would like to ask for help.
My issue is I want to stack 1 or 2 numbers in an Mtext strings selection and return the Mtext string with these numbers stacked.
For example I have strings like this one: 4 1/2"D Pipe B.+9' 3/4".
It is an Mtext object among Mtext objects that I would like to stack 1/2 and 3/4 and return the original string with numbers stacked.
I've followed by your code:
BlockTableRecord btrr = bt[BlockTableRecord.ModelSpace].GetObject(OpenMode.ForWrite) as BlockTableRecord;
foreach (ObjectId id in btrr)
{
Entity currentEntity = tr.GetObject(id, OpenMode.ForWrite, false, true) as Entity;
//Entity currentEntity = tr.GetObject(id, OpenMode.ForWrite, true) as Entity;
if (currentEntity == null)
{
continue;
}
if (currentEntity.GetType() == typeof(MText))
{
if (((MText)currentEntity).Contents == "H e l l o")
{
//currentEntity.UpgradeOpen();
((MText)currentEntity).Contents = "123";
//currentEntity.DowngradeOpen();
//TextEditor textEditor = TextEditor.CreateTextEditor((MText)currentEntity);
// textEditor.SelectAll();
// TextEditorSelection selection = textEditor.Selection;
// selection.InsertString("123");
// textEditor.Close(TextEditor.ExitStatus.ExitSave);
Autodesk.AutoCAD.ApplicationServices.Application.ShowAlertDialog(((MText)currentEntity).Contents + "--MText");
}
}
}
but result is text overlapping:
I've tried commented part individually but same result.
Thanks!
Can't find what you're looking for? Ask the community or share your knowledge.