Code Red => .NET => Topic started by: rugaroo on June 25, 2017, 05:41:50 PM

Title: .Net Leaders w/ Associated Blocks
Post by: rugaroo on June 25, 2017, 05:41:50 PM
Been looking around quite a bit, but haven't seemed to find anything that tackles what I am looking for, so hoping someone might have some insight.

I have been able to easily create MLeaders, Leaders, Leaders w/MText and whatnot with .Net, but I haven't really been having success doing so with Leaders that have associated blocks. I have some fairly detailed dynamic blocks that I want to associate to the end of a leader that the users ends up creating at the same time.

At first I figured Leader.BlockName or .BlockId would get me in the right direction but they are both read-only and I am scratching my head right now... Anyone have any ideas or directions that you could point me in? Programming this for 2016 AutoCAD if it helps.

Thanks in advance.
Title: Re: .Net Leaders w/ Associated Blocks
Post by: Jeff_M on June 25, 2017, 06:49:54 PM
Create the BlockReference then set the Mleader.BlockContentId to use the ObjectId of the blockreference.
Code - C#: [Select]
  1.             // Set up the Block contents
  2.             ml.MLeaderStyle = mlstyle;
  3.             MLeaderStyle style = (MLeaderStyle)mlstyle.Open(OpenMode.ForRead);
  4.             BlockReference br = new BlockReference(new Point3d(), style.BlockId);
  5.             ml.BlockContentId = br.ObjectId;
Title: Re: .Net Leaders w/ Associated Blocks
Post by: rugaroo on June 25, 2017, 10:10:13 PM
Thanks for the reply Jeff, doesn't seem like I can set the block though for a standard leader. If I was using MLeaders, yes this similar to what I use for that but for a standard leader there is no option to actually assign a BlockId from what I see. Again, I am just looking to create a standard leader with an associated dynamic block. Sorry if I was a little misleading.

This is what I am looking for kinda...
Code: [Select]
Using _LeaderItm As Leader = New Leader()
                Dim _BlkRef As BlockReference = New BlockReference(New Point3d(4, 4, 0), _LeaderItm.BlockId)
                _LeaderItm.AppendVertex(New Point3d(0, 0, 0))
                _LeaderItm.AppendVertex(New Point3d(4, 4, 0))
                ''' Somehow set block id below. '''
                _LeaderItm.BlockId '<- Readonly.
                _LeaderItm.BlockName '<- Readonly.
                ''' After block id set, finalize.'''
                _LeaderItm.HasArrowHead = True

                CurrentTrans.AddNewlyCreatedDBObject(_LeaderItm, True)
            End Using
Title: Re: .Net Leaders w/ Associated Blocks
Post by: Jeff_M on June 26, 2017, 11:22:47 AM
Oops, saw MLeader in the original post and missed that you were asking specifically about Leaders. Off to inestigate...
Title: Re: .Net Leaders w/ Associated Blocks
Post by: Jeff_M on June 26, 2017, 12:50:23 PM
This worked for me...add the BlockReference, add the Leader, assign the BlockRefId to the Annotation property of the Leader.
Code - C#: [Select]
  1.             var doc = Application.DocumentManager.MdiActiveDocument;
  2.             var db = doc.Database;
  3.             using (Transaction tr = db.TransactionManager.StartTransaction())
  4.             {
  5.                 var bt = (BlockTable)tr.GetObject(db.BlockTableId, OpenMode.ForRead);
  6.                 var blkId = bt["Circle"];
  7.                 var blkref = new BlockReference(new Point3d(0.5, 4, 0), blkId);
  8.                 var ms = (BlockTableRecord)tr.GetObject(bt[BlockTableRecord.ModelSpace], OpenMode.ForWrite);
  9.                 ms.AppendEntity(blkref);
  10.                 tr.AddNewlyCreatedDBObject(blkref, true);
  11.                 var ldr = new Leader();
  12.                 ldr.AppendVertex(new Point3d(0, 0, 0));
  13.                 ldr.AppendVertex(new Point3d(0, 4, 0));
  14.                 ms.AppendEntity(ldr);
  15.                 tr.AddNewlyCreatedDBObject(ldr, true);
  16.                 ldr.Annotation = blkref.ObjectId;
  17.                 tr.Commit();
  18.             }
  19.         }
Title: Re: .Net Leaders w/ Associated Blocks
Post by: rugaroo on June 26, 2017, 08:23:07 PM
See... This part is what was upsetting. Inserting the block first, then leader, then attaching... backasswards if i may say so. I was close at least, just didn't start at the end to get to the beginning of the end... All well... THANK YOU Jeff!
Title: Re: .Net Leaders w/ Associated Blocks
Post by: Bryco on June 26, 2017, 10:16:01 PM
If you insert the block at 0,0,0 you can still use a jig for the leader then transform the block and lastly set the leader annotation
Title: Re: .Net Leaders w/ Associated Blocks
Post by: rugaroo on June 27, 2017, 11:02:42 PM
Thanks Bryco, actually was able to get it working after what Jeff mentioned. I had to create the leader first, and then append the block afterwards. I am now stuck trying to get my dynamic block's attributes to show up properly. I saw a post here where gile had a neat SyncronizeAttributes module/function, but it doesn't appear as though I am using it correctly.

So a break down of what is happening, user enters construction note number, start point of leader, end point of leader, leader is created, block is inserted, command repeats until canceled... The issue I am at now is the fact that the construction note that the user enters does not actually show up until after the command is run a second time. So, please forgive me if my coding is sloppy or not commented. Thanks in advance as always.

Code: [Select]
Using _LeaderItm As Leader = New Leader()
                    Dim _NoteString As PromptStringOptions = New PromptStringOptions(vbLf & "Construction note number: ")
                    Dim _NoteStrRes As PromptResult = CurrentEd.GetString(_NoteString)
                    If _NoteStrRes.Status <> PromptStatus.OK Then Exit Do

                    Dim CurrentBlkTbl As BlockTable
                    CurrentBlkTbl = CurrentTrans.GetObject(CurrentDB.BlockTableId, OpenMode.ForRead)

                    Dim CurrentBlkTblRec As BlockTableRecord
                    CurrentBlkTblRec = CurrentTrans.GetObject(CurrentBlkTbl(BlockTableRecord.ModelSpace), OpenMode.ForWrite)

                    Dim _PntStartRes As PromptPointResult = CurrentEd.GetPoint(_PntStart)
                    If _PntStartRes.Status <> PromptStatus.OK Then Exit Do

                    _PntEnd.BasePoint = _PntStartRes.Value
                    Dim _PntEndRes As PromptPointResult = CurrentEd.GetPoint(_PntEnd)
                    If _PntEndRes.Status <> PromptStatus.OK Then Exit Do

                    Dim _RotMat As Matrix3d = CurrentEd.CurrentUserCoordinateSystem
                    Dim _BaseStartPnt As Point3d = _PntStartRes.Value.TransformBy(_RotMat)
                    Dim _BaseEndPnt As Point3d = _PntEndRes.Value.TransformBy(_RotMat)

                    Dim _BlkTbl As BlockTable = CurrentTrans.GetObject(CurrentDB.BlockTableId, OpenMode.ForRead)
                    Dim _BlkId = _BlkTbl(_BlkNameString)
                    Dim _BlkRef As BlockReference = New BlockReference(_BaseEndPnt, _BlkId)

                    _LeaderItm.HasArrowHead = True

                    CurrentTrans.AddNewlyCreatedDBObject(_LeaderItm, True)
                    CurrentTrans.AddNewlyCreatedDBObject(_BlkRef, True)
                    _LeaderItm.Annotation = _BlkRef.ObjectId

                    Dim _DynBlkRef As BlockReference = DirectCast(CurrentTrans.GetObject(_BlkRef.ObjectId, OpenMode.ForWrite), BlockReference)
                    Dim _DynBlkTblRec As BlockTableRecord = DirectCast(CurrentTrans.GetObject(_DynBlkRef.DynamicBlockTableRecord, OpenMode.ForWrite), BlockTableRecord)

                    For Each _AttID As ObjectId In _DynBlkTblRec
                        Dim ent As DBObject = CurrentTrans.GetObject(_AttID, OpenMode.ForWrite)
                        If TypeOf ent Is AttributeDefinition Then
                            Dim AttDef As AttributeDefinition = ent
                            If AttDef.Tag = "NT" Then AttDef.TextString = _NoteStrRes.StringResult
                        End If


                End Using