Author Topic: Setting Dynamic Block Values with VB.NET  (Read 1914 times)

0 Members and 1 Guest are viewing this topic.

cmwade77

  • Swamp Rat
  • Posts: 1443
Setting Dynamic Block Values with VB.NET
« on: January 25, 2024, 12:37:12 PM »
Please bear with me here, I am very new to .NET and I am having an issue with setting Dynamic Block Properties, this is the code I have:

Code - vb.net: [Select]
  1.     Public Sub SetProperty(BlockRef As BlockReference, PropName As String, NewValue As Object)
  2.         ' Use a transaction when modifying block properties
  3.         Using trans As Transaction = db.TransactionManager.StartTransaction()
  4.             Dim Prop As DynamicBlockReferenceProperty = GetProperty(BlockRef, PropName)
  5.             If Not IsNothing(Prop) Then
  6.                 If Not Prop.Value.Equals(NewValue) Then ' Check if the values are different
  7.                     Try
  8.                         ' Use Convert.ChangeType to convert NewValue to the property's data type                        
  9.                         Prop.Value = Convert.ChangeType(NewValue, Prop.Value.GetType())
  10.                         ' Commit the transaction after setting the property
  11.                         trans.Commit()
  12.                         ed.WriteMessage(vbCrLf & NewValue.ToString & "  Property: " & Prop.PropertyName & " set successfully to value of: " & Prop.Value.ToString)
  13.                     Catch ex As System.Exception
  14.                         ' Handle conversion error or unsupported data type
  15.                         ' You can log an error or provide a custom error message
  16.                         Console.WriteLine("Error: " & ex.Message)
  17.                     End Try
  18.                 End If
  19.             End If
  20.         End Using
  21.     End Sub
  22.  
  23.     Public Function GetProperty(BlockRef As BlockReference, PropName As String) As DynamicBlockReferenceProperty
  24.         If BlockRef.IsDynamicBlock Then
  25.             For Each Prop As DynamicBlockReferenceProperty In BlockRef.DynamicBlockReferencePropertyCollection
  26.                 If Not Prop.ReadOnly Then
  27.                     If Prop.PropertyName.ToLower = PropName.ToLower Then
  28.                         Return Prop
  29.                     End If
  30.                 End If
  31.             Next
  32.         End If
  33.         Return Nothing
  34.     End Function

When this code sets the property, sometimes things will stretch, but as you can see on the command line message, it still thinks the property value is the original 40 and if you look at the image, even the grip is still showing at the original 40, this would be for the property DUCT_1 in the attached block.

I am sure I am missing something obvious here, but I just don't know what.
« Last Edit: January 25, 2024, 01:03:16 PM by cmwade77 »

gile

  • Gator
  • Posts: 2507
  • Marseille, France
Re: Setting Dynamic Block Values with VB.NET
« Reply #1 on: January 25, 2024, 02:56:37 PM »
I am very new to .NET
So don't go any further with VB and switch to C#. You'll find a lot more help and examples in C#, and the difference between the two languages should become even greater with the forthcoming move to .NET 8.0.
Speaking English as a French Frog

kdub_nz

  • Mesozoic keyThumper
  • SuperMod
  • Water Moccasin
  • Posts: 2140
  • class keyThumper<T>:ILazy<T>
Re: Setting Dynamic Block Values with VB.NET
« Reply #2 on: January 25, 2024, 02:58:37 PM »
I was thinking of a way to say the same thing, then your reply popped up.
Called Kerry in my other life
Retired; but they dragged me back in !

I live at UTC + 13.00

---
some people complain about loading the dishwasher.
Sometimes the question is more important than the answer.

cmwade77

  • Swamp Rat
  • Posts: 1443
Re: Setting Dynamic Block Values with VB.NET
« Reply #3 on: January 25, 2024, 02:59:36 PM »
I already know enough VB to make this workable, I know nothing with C#

Jeff H

  • Needs a day job
  • Posts: 6150
Re: Setting Dynamic Block Values with VB.NET
« Reply #4 on: January 25, 2024, 02:59:40 PM »
Try calling BlockTableRecord.UpdateAnonymousBlocks Method
Guessing the AnonymousBlockTableRecord for that BlockReference has not updated.

One way to test really quick in UI is to open it Block Editor and save it then see if it updates.

If you only have access to the Blockreference then make sure you use the BlockReference.DynamicBlockTableRecord Property to get its blocktable record

gile

  • Gator
  • Posts: 2507
  • Marseille, France
Re: Setting Dynamic Block Values with VB.NET
« Reply #5 on: January 25, 2024, 04:09:15 PM »
The dynamic property value does not change because you do not Commit the Transaction you start in the SetProperty method.
You should not have to start a transaction in this method as you you pass it a DBObject (BlockReference) which should be already opened with or added to a Transaction in the calling code.

PS: your knowledge of VB won't help you that much in learning .NET. Learning C# isn't much compared to learning .NET in general and AutoCAD's .NET API.
« Last Edit: January 25, 2024, 04:19:27 PM by gile »
Speaking English as a French Frog

cmwade77

  • Swamp Rat
  • Posts: 1443
Re: Setting Dynamic Block Values with VB.NET
« Reply #6 on: January 25, 2024, 04:38:44 PM »
I am confused, wouldn't trans.Commit() commit this?

kdub_nz

  • Mesozoic keyThumper
  • SuperMod
  • Water Moccasin
  • Posts: 2140
  • class keyThumper<T>:ILazy<T>
Re: Setting Dynamic Block Values with VB.NET
« Reply #7 on: January 25, 2024, 05:07:28 PM »
Hi Chris,
Not if an error occurs earlier in the try statement.

Move the statement either to just prior the End Using or incorporate it in a finally block.

. . . if I understand the question . .

but a Gilles mentions, the transaction ( and commit ) declaration should be in the calling method.

Regards,
« Last Edit: January 25, 2024, 05:11:02 PM by kdub_nz »
Called Kerry in my other life
Retired; but they dragged me back in !

I live at UTC + 13.00

---
some people complain about loading the dishwasher.
Sometimes the question is more important than the answer.

cmwade77

  • Swamp Rat
  • Posts: 1443
Re: Setting Dynamic Block Values with VB.NET
« Reply #8 on: January 25, 2024, 06:41:27 PM »
Hmm, it seems to update somewhat, but not always accurate still with the adjusted code below, more concerning is that I cannot use the grips afterwards. In this code, it tells me it cannot find the property DUCT_1 in the block, even though it is indeed there:

Code - vb.net: [Select]
  1. Imports System
  2. Imports System.Collections.Generic
  3. Imports System.Text
  4. Imports Autodesk.AutoCAD.DatabaseServices
  5. Imports Autodesk.AutoCAD.GraphicsInterface
  6. Imports Autodesk.AutoCAD.Runtime
  7. Imports Autodesk.AutoCAD.Geometry
  8. Imports Autodesk.AutoCAD.ApplicationServices
  9. Imports Autodesk.AutoCAD.ApplicationServices.Application
  10. Imports Autodesk.AutoCAD.EditorInput
  11. Imports System.IO
  12. Imports System.Security.Cryptography
  13. Imports Autodesk.AutoCAD.Windows
  14. Imports System.Windows.Interop
  15. Module AutoCADFunctions
  16.     Public Sub InsertBlock(BlkName As String)
  17.         Dim bRollup As Boolean = ps.AutoRollUp
  18.         If ps.Dock.Equals(DockSides.None) Then
  19.             If ps.Style.Equals(32) Then
  20.                 ps.Style = 0
  21.             End If
  22.             With ps
  23.                 .AutoRollUp = True
  24.                 .Visible = False
  25.                 .Visible = True
  26.             End With
  27.             ps.AutoRollUp = bRollup
  28.         End If
  29.         BlkName = Duct_Shape & "_" & BlkName
  30.         Dim FullPath As String = Directory.GetCurrentDirectory & "\Blocks\" & BlkName & ".dwg"
  31.         Using xDb As New Database(False, True)
  32.             xDb.ReadDwgFile(FullPath, FileShare.Read, True, Nothing)
  33.             Using DocLock As DocumentLock = doc.LockDocument
  34.                 Try
  35.                     Dim Id As ObjectId = db.Insert(BlkName, xDb, True)
  36.                     If Id.IsNull Then
  37.                         ed.WriteMessage(vbLf & "Failed to insert block")
  38.                         Return
  39.                     End If
  40.                     Using tr As Transaction = db.TransactionManager.StartTransaction()
  41.                         Try
  42.                             Dim bt As BlockTable =
  43.                     DirectCast(tr.GetObject(db.BlockTableId, OpenMode.ForRead), BlockTable)
  44.                             If Not bt.Has(BlkName) Then
  45.                                 ed.WriteMessage(vbLf & "Block '{0}' not found.", BlkName)
  46.                                 Return
  47.                             End If
  48.  
  49.                             Dim pr As PromptResult
  50.                             Using br As New BlockReference(Point3d.Origin, bt(BlkName))
  51.                                 br.TransformBy(ed.CurrentUserCoordinateSystem)
  52.  
  53.                                 ' Using InsertBlockJig class to insert the block
  54.                                 Dim insertJig As New InsertBlockJig(br)
  55.                                 pr = ed.Drag(insertJig)
  56.                                 If pr.Status <> PromptStatus.OK Then
  57.                                     Return
  58.                                 End If
  59.  
  60.                                 ' Using RotateBlockJig class to rotate the block
  61.                                 Dim rotateJig As New RotateBlockJig(br)
  62.                                 pr = ed.Drag(rotateJig)
  63.                                 If pr.Status <> PromptStatus.OK Then
  64.                                     Return
  65.                                 End If
  66.                                 rotateJig.UpdateRotation()
  67.  
  68.                                 Dim btr As BlockTableRecord =
  69.                                 DirectCast(tr.GetObject(db.CurrentSpaceId, OpenMode.ForWrite), BlockTableRecord)
  70.                                 btr.AppendEntity(br)
  71.                                 tr.AddNewlyCreatedDBObject(br, True)
  72.  
  73.                                 If Not IsNothing(btr) Then
  74.                                     btr.UpdateAnonymousBlocks()
  75.                                 End If
  76.                                 tr.Commit()
  77.                                 Dim Prop As DynamicBlockReferenceProperty = GetProperty(br, "DUCT_1")
  78.                                 If Not IsNothing(Prop) Then
  79.                                     ed.WriteMessage(vbCrLf & "Property: " & Prop.PropertyName & " set successfully to value of: " & Prop.Value.ToString)
  80.                                 Else
  81.                                     ed.WriteMessage(vbCrLf & "Could not find DUCT_1 property in block " & br.Name)
  82.                                 End If
  83.                             End Using
  84.  
  85.                         Catch Ex As System.AccessViolationException
  86.                         End Try
  87.                     End Using
  88.                 Catch Ex As System.AccessViolationException
  89.                 End Try
  90.             End Using
  91.  
  92.         End Using
  93.         Duct_Distance = 0
  94.  
  95.     End Sub
  96.     Public Sub SetProperty(BlockRef As BlockReference, PropName As String, NewValue As Object)
  97.  
  98.  
  99.         Dim Prop As DynamicBlockReferenceProperty = GetProperty(BlockRef, PropName)
  100.         If Not IsNothing(Prop) Then
  101.             If Not Prop.Value.Equals(NewValue) Then ' Check if the values are different
  102.                 Try
  103.                     ' Use Convert.ChangeType to convert NewValue to the property's data type                        
  104.                     Prop.Value = Convert.ChangeType(NewValue, Prop.Value.GetType())
  105.                 Catch ex As System.Exception
  106.                     ' Handle conversion error or unsupported data type
  107.                     ' You can log an error or provide a custom error message
  108.                     Console.WriteLine("Error: " & ex.Message)
  109.                 End Try
  110.             End If
  111.         End If
  112.     End Sub
  113.     Public Function GetProperty(BlockRef As BlockReference, PropName As String) As DynamicBlockReferenceProperty
  114.         If BlockRef.IsDynamicBlock Then
  115.             For Each Prop As DynamicBlockReferenceProperty In BlockRef.DynamicBlockReferencePropertyCollection
  116.                 If Not Prop.ReadOnly Then
  117.                     If Prop.PropertyName.ToLower = PropName.ToLower Then
  118.                         Return Prop
  119.                     End If
  120.                 End If
  121.             Next
  122.         End If
  123.         Return Nothing
  124.     End Function
  125.  
  126.     Public Sub SetDuct(br As BlockReference)
  127.         If Duct_Distance > 0 Then
  128.             SetProperty(br, "DUCT_1", Duct_Distance)
  129.         End If
  130.     End Sub
  131.     Sub forsafekeeping(br As BlockReference)
  132.         If Duct_Width > 0 Then
  133.             If Insulation_KeepClear Then
  134.                 SetProperty(br, "SIZE_1", Duct_Width + Insulation_Clear_Size)
  135.             Else
  136.                 SetProperty(br, "SIZE_1", Duct_Width)
  137.  
  138.             End If
  139.         End If
  140.         SetProperty(br, "INSULATION", Insulation_Type)
  141.         If Insulation_Type <> "NONE" Then
  142.             If Insulation_Internal_Size > 0 Then
  143.                 SetProperty(br, "INSULATION_INTERNAL", Insulation_Internal_Size)
  144.             End If
  145.             If Insulation_External_Size > 0 Then
  146.                 SetProperty(br, "INSULATION_EXTERNAL", Insulation_External_Size)
  147.             End If
  148.         End If
  149.     End Sub
  150. End Module
  151. Class InsertBlockJig
  152.     Inherits EntityJig
  153.  
  154.     ' Protected fields
  155.     Protected position As Point3d
  156.     Protected br As BlockReference
  157.  
  158.     ' Constructor (fields initialization)
  159.     Public Sub New(br As BlockReference)
  160.         MyBase.New(br)
  161.         Me.br = br
  162.         Me.position = br.Position
  163.  
  164.     End Sub
  165.  
  166.     ' Prompts the user to specify the insertion point (EntityJig implementation)
  167.     Protected Overrides Function Sampler(prompts As JigPrompts) As SamplerStatus
  168.         Dim msg As String = vbLf & "Specify the insertion point: "
  169.         Dim jppo As New JigPromptPointOptions(msg)
  170.         jppo.UserInputControls = (UserInputControls.Accept3dCoordinates Or
  171.                                       UserInputControls.NullResponseAccepted)
  172.         Dim ppr As PromptPointResult = prompts.AcquirePoint(jppo)
  173.         If Me.position.DistanceTo(ppr.Value) < Tolerance.[Global].EqualPoint Then
  174.             Return SamplerStatus.NoChange
  175.         Else
  176.             SetDuct(Me.br)
  177.             Me.position = ppr.Value
  178.         End If
  179.         Return SamplerStatus.OK
  180.     End Function
  181.  
  182.     ' Updates the bloc position (EntityJig implementation)
  183.     Protected Overrides Function Update() As Boolean
  184.         Me.br.Position = Me.position
  185.  
  186.         Return True
  187.     End Function
  188. End Class
  189.  
  190. Class RotateBlockJig
  191.     Inherits EntityJig
  192.  
  193.     ' Private fields
  194.     Protected br As BlockReference
  195.     Protected rot As Double, ucsRot As Double
  196.  
  197.     ' Constructor
  198.     Public Sub New(br As BlockReference)
  199.         MyBase.New(br)
  200.         Me.br = br
  201.         Me.ucsRot = br.Rotation
  202.  
  203.     End Sub
  204.  
  205.     ' Prompts the user to specify the rotation (EntityJig implementation)
  206.     Protected Overrides Function Sampler(prompts As JigPrompts) As SamplerStatus
  207.         Dim BasePoint As Point3d = Me.br.Position
  208.         Dim jpao As New JigPromptPointOptions(vbLf & "Specify Duct EndPoint: ")
  209.         'JigPromptAngleOptions(vbLf & "Specify the rotation: ")
  210.         jpao.DefaultValue = BasePoint
  211.         jpao.UseBasePoint = True
  212.         jpao.BasePoint = BasePoint
  213.         jpao.Cursor = CursorType.RubberBand
  214.         jpao.UserInputControls = (UserInputControls.Accept3dCoordinates Or
  215.                                       UserInputControls.UseBasePointElevation Or
  216.                                       UserInputControls.NullResponseAccepted)
  217.         Dim pt As PromptPointResult = prompts.AcquirePoint(jpao)
  218.         Dim NewPt As Point3d = pt.Value
  219.         Dim Pt1 As New Point2d(BasePoint.X, BasePoint.Y)
  220.         Dim Pt2 As New Point2d(NewPt.X, NewPt.Y)
  221.         Dim NewAngle As Double = Pt1.GetVectorTo(Pt2).Angle
  222.         Duct_Distance = Pt1.GetDistanceTo(Pt2)
  223.         SetDuct(Me.br)
  224.         If Me.rot = NewAngle Then
  225.             Return SamplerStatus.NoChange
  226.         Else
  227.             Me.rot = NewAngle
  228.             Return SamplerStatus.OK
  229.         End If
  230.     End Function
  231.  
  232.     ' Updates the bloc rotation (EntityJig implementation)
  233.     Protected Overrides Function Update() As Boolean
  234.         UpdateRotation()
  235.         Return True
  236.     End Function
  237.  
  238.     ' Updates the bloc rotation (mandatory for the 'default' option)
  239.     ' This method is called from the method where the jig is created
  240.     Friend Sub UpdateRotation()
  241.         Me.br.Rotation = Me.rot + Me.ucsRot
  242.         'SetDuct(Me.br)
  243.     End Sub
  244. End Class

I am sure it is something stupid and obvious.

Jeff H

  • Needs a day job
  • Posts: 6150
Re: Setting Dynamic Block Values with VB.NET
« Reply #9 on: January 25, 2024, 06:56:51 PM »
Your calling UpadteAnonymousBlocks on Model Space.
You need to call it on whatever "BlkName" is

kdub_nz

  • Mesozoic keyThumper
  • SuperMod
  • Water Moccasin
  • Posts: 2140
  • class keyThumper<T>:ILazy<T>
Re: Setting Dynamic Block Values with VB.NET
« Reply #10 on: January 25, 2024, 06:58:51 PM »
<scrapped>
Jeff beat me.

added:
My head hurts,
. . . there's a reason I haven't touched xVBx in 20 odd years.

Called Kerry in my other life
Retired; but they dragged me back in !

I live at UTC + 13.00

---
some people complain about loading the dishwasher.
Sometimes the question is more important than the answer.

cmwade77

  • Swamp Rat
  • Posts: 1443
Re: Setting Dynamic Block Values with VB.NET
« Reply #11 on: January 25, 2024, 07:01:36 PM »
Oki, makes sense, but how do I get the blocktablerecord for that? Blkname is just the string that represents the block name

br is the block reference itself.

kdub_nz

  • Mesozoic keyThumper
  • SuperMod
  • Water Moccasin
  • Posts: 2140
  • class keyThumper<T>:ILazy<T>
Re: Setting Dynamic Block Values with VB.NET
« Reply #12 on: January 25, 2024, 07:15:43 PM »
Just a note, because I see this a lot:
Though technically correct,
Code - vb.net: [Select]
  1.    Dim btr As BlockTableRecord =
  2.          DirectCast(tr.GetObject(db.CurrentSpaceId, OpenMode.ForWrite), BlockTableRecord)
  3.  

is better written:
Code - vb.net: [Select]
  1.    Dim currentSpace As BlockTableRecord =
  2.          DirectCast(tr.GetObject(db.CurrentSpaceId, OpenMode.ForWrite), BlockTableRecord)
  3.  
and make the refactors required.
This naming is more indicative of intent , and reduces misinterpretation.
« Last Edit: January 25, 2024, 07:18:44 PM by kdub_nz »
Called Kerry in my other life
Retired; but they dragged me back in !

I live at UTC + 13.00

---
some people complain about loading the dishwasher.
Sometimes the question is more important than the answer.

cmwade77

  • Swamp Rat
  • Posts: 1443
Re: Setting Dynamic Block Values with VB.NET
« Reply #13 on: January 25, 2024, 07:22:33 PM »
That certainly makes sense, I have tried adjusting the code to this and I am getting the same results:

Code - vb.net: [Select]
  1.     Public Sub InsertBlock(BlkName As String)
  2.         Dim bRollup As Boolean = ps.AutoRollUp
  3.         If ps.Dock.Equals(DockSides.None) Then
  4.             If ps.Style.Equals(32) Then
  5.                 ps.Style = 0
  6.             End If
  7.             With ps
  8.                 .AutoRollUp = True
  9.                 .Visible = False
  10.                 .Visible = True
  11.             End With
  12.             ps.AutoRollUp = bRollup
  13.         End If
  14.         BlkName = Duct_Shape & "_" & BlkName
  15.         Dim FullPath As String = Directory.GetCurrentDirectory & "\Blocks\" & BlkName & ".dwg"
  16.         Using xDb As New Database(False, True)
  17.             xDb.ReadDwgFile(FullPath, FileShare.Read, True, Nothing)
  18.             Using DocLock As DocumentLock = doc.LockDocument
  19.                 Try
  20.                     Dim Id As ObjectId = db.Insert(BlkName, xDb, True)
  21.                     If Id.IsNull Then
  22.                         ed.WriteMessage(vbLf & "Failed to insert block")
  23.                         Return
  24.                     End If
  25.                     Using tr As Transaction = db.TransactionManager.StartTransaction()
  26.                         Try
  27.                             Dim bt As BlockTable =
  28.                     DirectCast(tr.GetObject(db.BlockTableId, OpenMode.ForRead), BlockTable)
  29.                             If Not bt.Has(BlkName) Then
  30.                                 ed.WriteMessage(vbLf & "Block '{0}' not found.", BlkName)
  31.                                 Return
  32.                             End If
  33.  
  34.                             Dim pr As PromptResult
  35.                             Using br As New BlockReference(Point3d.Origin, bt(BlkName))
  36.                                 br.TransformBy(ed.CurrentUserCoordinateSystem)
  37.  
  38.                                 ' Using InsertBlockJig class to insert the block
  39.                                 Dim insertJig As New InsertBlockJig(br)
  40.                                 pr = ed.Drag(insertJig)
  41.                                 If pr.Status <> PromptStatus.OK Then
  42.                                     Return
  43.                                 End If
  44.  
  45.                                 ' Using RotateBlockJig class to rotate the block
  46.                                 Dim rotateJig As New RotateBlockJig(br)
  47.                                 pr = ed.Drag(rotateJig)
  48.                                 If pr.Status <> PromptStatus.OK Then
  49.                                     Return
  50.                                 End If
  51.                                 rotateJig.UpdateRotation()
  52.  
  53.                                 Dim currentSpace As BlockTableRecord =
  54.                                 DirectCast(tr.GetObject(db.CurrentSpaceId, OpenMode.ForWrite), BlockTableRecord)
  55.                                 currentSpace.AppendEntity(br)
  56.                                 tr.AddNewlyCreatedDBObject(br, True)
  57.  
  58.                                 Dim btr As BlockTableRecord = DirectCast(tr.GetObject(br.BlockTableRecord, OpenMode.ForWrite), BlockTableRecord)
  59.                                 If Not IsNothing(btr) Then
  60.                                     btr.UpdateAnonymousBlocks()
  61.                                 End If
  62.  
  63.                                 tr.Commit()
  64.                                 Dim Prop As DynamicBlockReferenceProperty = GetProperty(br, "DUCT_1")
  65.                                 If Not IsNothing(Prop) Then
  66.                                     ed.WriteMessage(vbCrLf & "Property: " & Prop.PropertyName & " set successfully to value of: " & Prop.Value.ToString)
  67.                                 Else
  68.                                     ed.WriteMessage(vbCrLf & "Could not find DUCT_1 property in block " & br.Name)
  69.                                 End If
  70.                             End Using
  71.  
  72.                         Catch Ex As System.AccessViolationException
  73.                         End Try
  74.                     End Using
  75.                 Catch Ex As System.AccessViolationException
  76.                 End Try
  77.             End Using
  78.         End Using
  79.         Duct_Distance = 0
  80.     End Sub

gile

  • Gator
  • Posts: 2507
  • Marseille, France
Re: Setting Dynamic Block Values with VB.NET
« Reply #14 on: January 26, 2024, 03:26:27 AM »
It seems that you want to do a lot of things at once in this method, which makes things confusing (even for you apparently).
  • You should test whether the block table doesn't already contain the block before inserting the file with (db.Insert ...).
  • As your method is called in the context of the application (from a non-modal UI), you should define a command (CommandMethod) that you call from the Palette with SendStringToExecute. This lets AutoCAD lock the document and allows you to call and test the method without the palette.
  • You should not mix hard coded names ("DUCT_1") and parameters (blockName) in the same method.
  • Duct_Distance should be a public property of the RotateBlockJig class.
  • You should report exception messages instead of hiding them.

The following code seems to work as expected. It uses the "hard-coding' way to insert a "ROUND_DUCT" block which we know has a dynamic property named "DUCT_1" whose value is of type double.
Code - C#: [Select]
  1.         [CommandMethod("INSERT_ROUND_DUCT")]
  2.         public static void InsertRoundDuctBlock()
  3.         {
  4.             var doc = Application.DocumentManager.MdiActiveDocument;
  5.             var db = doc.Database;
  6.             var ed = doc.Editor;
  7.             using (var tr = db.TransactionManager.StartTransaction())
  8.             {
  9.                 // Get the ObjectId of the "ROUND_DUCT" block definition
  10.                 var btrId = GetBlock("ROUND_DUCT", db);
  11.                 if (btrId.IsNull)
  12.                 {
  13.                     ed.WriteMessage("\nBlock 'ROUND_DUCT' not found.");
  14.                     return;
  15.                 }
  16.                 using (var br = new BlockReference(Point3d.Origin, btrId))
  17.                 {
  18.                     // Insert and rotate a new reference of "ROUND_DUCT"
  19.                     br.TransformBy(ed.CurrentUserCoordinateSystem);
  20.  
  21.                     var insertJig = new InsertBlockJig(br);
  22.                     var promptResult = ed.Drag(insertJig);
  23.                     if (promptResult.Status != PromptStatus.OK)
  24.                         return;
  25.  
  26.                     var rotateJig = new RotateBlockJig(br);
  27.                     promptResult = ed.Drag(rotateJig);
  28.                     if (promptResult.Status != PromptStatus.OK)
  29.                         return;
  30.  
  31.                     var currentSpace = (BlockTableRecord)tr.GetObject(db.CurrentSpaceId, OpenMode.ForWrite);
  32.                     currentSpace.AppendEntity(br);
  33.                     tr.AddNewlyCreatedDBObject(br, true);
  34.  
  35.                     // Resize the block reference using the "DUCT_1" dynamic property and the 'RotateJig.DuctDistance value
  36.                     foreach (DynamicBlockReferenceProperty property in br.DynamicBlockReferencePropertyCollection)
  37.                     {
  38.                         if (property.PropertyName == "DUCT_1")
  39.                         {
  40.                             property.Value = rotateJig.DuctDistance;
  41.                             break;
  42.                         }
  43.                     }
  44.                 }
  45.                 tr.Commit();
  46.             }
  47.         }
  48.  
  49.         private static ObjectId GetBlock(string blockName, Database db)
  50.         {
  51.             var blockTable = (BlockTable)db.BlockTableId.GetObject(OpenMode.ForRead);
  52.             if (blockTable.Has(blockName))
  53.             {
  54.                 return blockTable[blockName];
  55.             }
  56.             string fileName = Path.Combine(Directory.GetCurrentDirectory(), $@"Block\{blockName}.dwg");
  57.             {
  58.                 using (var xDb = new Database(false, true))
  59.                 {
  60.                     xDb.ReadDwgFile(fileName, FileOpenMode.OpenForReadAndAllShare, true, null);
  61.                     return db.Insert(fileName, xDb, true);
  62.                 }
  63.             }
  64.             return ObjectId.Null;
  65.         }

From your Palette, you can simply do:
Code - C#: [Select]
  1.         public static void FromPalette()
  2.         {
  3.             var doc = Application.DocumentManager.MdiActiveDocument;
  4.             doc.SendStringToExecute("INSERT_ROUND_DUCT\n", false, false, false);
  5.         }

Or, if I don't misunderstand what you're trying to do with the palette (set AutoRollUp to true during the Jig and reset its preious value after if completes), you have to call the InsertRoundDuct command synchronously:
Code - C#: [Select]
  1.         private void button3_Click(object sender, EventArgs e)
  2.         {
  3.             var ps = Commands.Palette;
  4.             bool rollup = ps.AutoRollUp;
  5.             if (ps.Dock == DockSides.None && ps.Style.HasFlag(PaletteSetStyles.Snappable))
  6.             {
  7.                 ps.Style &= ~PaletteSetStyles.Snappable;
  8.             }
  9.             ps.AutoRollUp = true;
  10.             var doc = AcAp.DocumentManager.MdiActiveDocument;
  11.             var ed = doc.Editor;
  12.             AcAp.DocumentManager.ExecuteInCommandContextAsync(
  13.                 (_) =>
  14.                 {
  15.                     ed.Command("INSERT_ROUND_DUCT");
  16.                     ps.AutoRollUp = rollup;
  17.                     return Task.CompletedTask;
  18.                 },
  19.                 null);
  20.         }


« Last Edit: January 29, 2024, 02:56:10 AM by gile »
Speaking English as a French Frog