Accessing the active space or layout in an AutoCAD drawing using .NET

This question was asked as comment to a previous post by har!s:

Thanks a lot for the code. I have yet to see 2008 and MultiLeader. But I presume that it works on both Model and paper spaces. In that case, what is the best method to make the operation space independent? i.e., it should work on active space irrespective of whether it's model or paper. I think this will be generally applicable to almost all the entity creations.

The question is very valid and does indeed apply to a lot of entity creation - and other - activities. Most of the time I simply show how to open the modelspace in my code, for example:

  Document doc =

    Application.DocumentManager.MdiActiveDocument;

  Editor ed = doc.Editor;

  Database db = doc.Database;

  Transaction tr =

    db.TransactionManager.StartTransaction();

  using (tr)

  {

    BlockTable bt =

      (BlockTable)tr.GetObject(

        db.BlockTableId,

        OpenMode.ForRead

      );

    BlockTableRecord btr =

      (BlockTableRecord)tr.GetObject(

        bt[BlockTableRecord.ModelSpace],

        OpenMode.ForWrite

      );

    // ...

  }

The key statement here is at the end, where we use GetObject() to open the BlockTableRecord to which we want to (for example) append an entity. The form we use is:

  bt[BlockTableRecord.ModelSpace]

Breaking this down: we're actually looking up the ObjectId of the BlockTableRecord with the name of "*MODEL_SPACE", which is the string stored in the static ModelSpace property of the BlockTableRecord class.

Here are a few different options for what we might do here:

  1. Use either BlockTableRecord.ModelSpace or BlockTableRecord.PaperSpace, if we know that we want to access either of these containers (the current approach).
  2. Use foreach() on the BlockTable to iterate through the various BlockTableRecords: you can open each one using GetObject() and check the IsLayout property to find those that are either modelspace or paperspace layouts.
  3. Use db.CurrentSpaceId to open the currently active space in that particular database.

Option 3 is really the answer to this question, which makes the code like this:

  Document doc =

    Application.DocumentManager.MdiActiveDocument;

  Editor ed = doc.Editor;

  Database db = doc.Database;

  Transaction tr =

    db.TransactionManager.StartTransaction();

  using (tr)

  {

    BlockTable bt =

      (BlockTable)tr.GetObject(

        db.BlockTableId,

        OpenMode.ForRead

      );

    BlockTableRecord btr =

      (BlockTableRecord)tr.GetObject(

        db.CurrentSpaceId,

        OpenMode.ForWrite

      );

    // ...

  }

7 responses to “Accessing the active space or layout in an AutoCAD drawing using .NET”

  1. You used the islayout qualifier to cal the proper block you are looking for in theis sequence. Is there a way to change the props of a block that is not a layout but rather just an ordinary modelspace designed block. I am having trouble as I seem to need to end the transaction of insert before I can access the dynamic props. But now how do I reselect the block without actually clicking it again to make it active? Any help would be appreciated

  2. It's not clear exactly what you need... you'll have to post some code, ideally to the AutoCAD .NET discussion group. You can then submit a link to the post as a comment, of course.

    Regards,

    Kean

  3. your article is so helpful. Could you explain this event?I have tried many times to create a box,and failed every time. the original code was almost the same except one:

    BlockTableRecord btr = (BlockTableRecord)trans.GetObject(bt[BlockTableRecord.ModelSpace], OpenMode.ForWrite);

    once i changed the code into:

    BlockTableRecord btr =(BlockTableRecord)tr.GetObject(db.CurrentSpaceId,OpenMode.ForWrite);

    everything goes exactly as i excepted, so why?
    CurrentSpaceId & ModelSpace?

  4. I don't know. Without seeing the context in which the code it called (stepping through via the debugger), and seeing the error itself, I can't tell you.

    Try posting a larger, non-confidential sample to the ADN team, if you're a member, or otherwise the AutoCAD .NET Discussion Group.

    Kean

  5. Евгений Хрущ Avatar
    Евгений Хрущ

    How I can change CurrentSpaceId without LayoutManager (when only Database.ReadDWGFile used)?

    1. Have you tried setting Database.Tilemode?

      Kean

      1. Евгений Хрущ Avatar
        Евгений Хрущ

        This is what I needed! Thank you very much!

Leave a Reply to castor Cancel reply

Your email address will not be published. Required fields are marked *