Author Topic: Updating MTEXT C#  (Read 404 times)

0 Members and 1 Guest are viewing this topic.

nocent

  • Mosquito
  • Posts: 5
Updating MTEXT C#
« on: March 22, 2017, 03:53:31 pm »
Update: Resolved by only passing in 1 argument into this method.

Hi all,
Beginner developer and autocad API user here whos had no luck googling this.  Hoping someone can point me in the right direction.
The goal is to update the mtext .contents.  The following code "opened .ForRead" can read mtext.contents perfectly fine. However, when i try to ".forWrite" i get the following exception:
Autodesk.AutoCAD.Runtime.Exception' in AcdbMgd.dll

Walking through the code it fails on line:
Quote
var obj = tr.GetObject(id, OpenMode.ForRead);
- but only on write mode.
The handle im passing in points back to an mtext object, and appears to be getting the correct object ID during conversion.  I havent eliminated this to be cause the caues of the problem however.

Does anyone have any code i can refer to for updating MText or could point me in the right direction?



Code: [Select]
public static void editMtextContents(string handle, string newValue)
{
Document doc = Application.DocumentManager.MdiActiveDocument;
Database db = doc.Database;

Handle hn = new Handle(ConvertHandleToInt(handle));

Transaction tr = db.TransactionManager.StartTransaction();
using (tr)
{
ObjectId id = db.GetObjectId(false, hn, 0);
var obj = tr.GetObject(id, OpenMode.ForWrite, false);
var mtext = obj as MText;
mtext.Contents = newValue;

tr.Commit();
}
}

Thanks!  -Bruce

Updates:
  • Using Autocad 2015
  • Drawings/layers arent locked
« Last Edit: March 23, 2017, 09:15:11 am by nocent »

Jeff H

  • Needs a day job
  • Posts: 5777
Re: Updating MTEXT C#
« Reply #1 on: March 22, 2017, 06:42:00 pm »
Was there anymore information with error?
Maybe on locked layer?


nocent

  • Mosquito
  • Posts: 5
Re: Updating MTEXT C#
« Reply #2 on: March 23, 2017, 07:32:32 am »
The layers arent locked, ive tried it on several drawings to try to weed out that dwg itself being the issue.
This is with using autocad 2015.


MexicanCustard

  • Swamp Rat
  • Posts: 666
Re: Updating MTEXT C#
« Reply #3 on: March 23, 2017, 08:19:04 am »
Can you post the drawing your working in?
AMEP 2017 64bit Win 10

nocent

  • Mosquito
  • Posts: 5
Re: Updating MTEXT C#
« Reply #4 on: March 23, 2017, 09:12:15 am »
I came through the issue (workaround?)!

The method doesnt work when passing in two arguments.  The fix was to fix the method signature to accept one argument, in my case an object that carried the handle and new value.

Phew!

kdub

  • SuperMod
  • Swamp Rat
  • Posts: 905
  • class keyThumper<T>:ILazy<T>
Re: Updating MTEXT C#
« Reply #5 on: March 24, 2017, 12:17:57 am »

@ nocent,

Sorry, I can't quite grasp your description of your solution.

Can you post the revised method please ? And show how you are calling the method.




Also, how are you determining the handle, do you have the string stored somewhere as external data ?

Regards,
called Kerry in my other life

Sometimes the question is more important than the answer.

nocent

  • Mosquito
  • Posts: 5
Re: Updating MTEXT C#
« Reply #6 on: March 24, 2017, 03:57:54 pm »
Hi Ken,

Method i was having trouble with (note i also had to add the "document lock" to solve the issue production):
Code: [Select]
public static void EditMtextContents(UpdatedTag tag)
{
Document doc = Autodesk.AutoCAD.ApplicationServices.Application.DocumentManager.MdiActiveDocument;
Database db = doc.Database;

//create handle from long int
Handle hn = new Handle(ConvertHandleToInt(tag.Handle));

//attempt to get an ObjectID for the handle
ObjectId id = db.GetObjectId(false, hn, 0);

//open the object to edit it
using (DocumentLock doclock = doc.LockDocument())
{
Transaction tr = doc.TransactionManager.StartTransaction();
using (tr)
{
DBObject obj = tr.GetObject(id, OpenMode.ForWrite);
//testing editing mtext contents
MText mtext = obj as MText;
mtext.Contents = tag.NewValue;
tr.Commit();
}
}
}

Updated tag is just a small simple class:
Code: [Select]
public class UpdatedTag
{
public string Handle { get; set; }
public string NewValue { get; set; }

public UpdatedTag(string handle, string newValue)
{
Handle = handle;
NewValue = newValue;
}
}

I extract all the mtext and store it in a list/dataset.  part of that information is its "handle" in acad terms. 
i convert the string handle to an autocad object handle using (i believe i got this off from Kean, either way hes been a huge resource):
Code: [Select]
public class UpdatedTag
{
public string Handle { get; set; }
public string NewValue { get; set; }

public UpdatedTag(string handle, string newValue)
{
Handle = handle;
NewValue = newValue;
}
}


Hope this is more helpful than confusing - am very much new to acad and development in general :)

MexicanCustard

  • Swamp Rat
  • Posts: 666
Re: Updating MTEXT C#
« Reply #7 on: March 27, 2017, 07:57:50 am »
Are you storing the UpdatedTag object between sessions?  If not, then why not just use the ObjectId?
AMEP 2017 64bit Win 10

MexicanCustard

  • Swamp Rat
  • Posts: 666
Re: Updating MTEXT C#
« Reply #8 on: March 27, 2017, 07:59:39 am »
Also instead of
Code - C#: [Select]
  1. Transaction tr = doc.TransactionManager.StartTransaction();
  2. using (tr)

You can
Code - C#: [Select]
  1. using (Transaction tr = doc.TransactionManager.StartTransaction())
AMEP 2017 64bit Win 10

MexicanCustard

  • Swamp Rat
  • Posts: 666
Re: Updating MTEXT C#
« Reply #9 on: March 27, 2017, 08:07:36 am »
if your in C# 6
Code - C#: [Select]
  1. using (var doclock = doc.LockDocument())
  2. {
  3. using (var tr = doc.TransactionManager.StartTransaction();)
  4. {
  5. var mtext = tr.GetObject(id, OpenMode.ForWrite) as MText;
  6.                        if(mtext != null)
  7.                        {
  8.                               mtext.Contents = tag.NewValue;
  9.                         }
  10.  
  11. tr.Commit();
  12. }
  13. }

If you've started using C#7
Code - C#: [Select]
  1. using (var doclock = doc.LockDocument())
  2. {
  3. using (var tr = doc.TransactionManager.StartTransaction())
  4. {
  5.                       if(tr.GetObject(id, OpenMode.ForWrite) is MText mtext)
  6.      mtext.Contents = tag.NewValue;
  7. tr.Commit();
  8. }
  9. }
AMEP 2017 64bit Win 10

nocent

  • Mosquito
  • Posts: 5
Re: Updating MTEXT C#
« Reply #10 on: March 28, 2017, 08:28:41 am »
Are you storing the UpdatedTag object between sessions?  If not, then why not just use the ObjectId?

Its a single session.  Thanks for sharing the improved code, much better readability!  :-D