I have a problem with updating the visual state of my dynamic block after changing its properties according to its propertiesTable, by code.
In a first transaction I place the block at the right position. Then, in a second transaction I try to set the dynamic properties of the blockreference by the subroutine below, changing its flipstate.
First, after setting all the dynamic property values, only the check(v) in the propertiesTable (lookup table) was set correct, but the dynamic block didn't flip.
Because the dynamic block contains a flip parameter with the VisibleInCurrentVisibilityState= false and a textual parameter in the PropertiesTable "Left/Right" for the user to select, I tried only to set the "hidden" flip parameter,
If DynBlockRefProp.VisibleInCurrentVisibilityState = blnVisualParameters
With as a result that the dynamic block did flip, but the check in the propertiesTable was still on the default row.
Third try, I run the subroutine bellow twice, first setting teh 'hidden' properties, secondly setting the 'visible' parameters. Unfortunately, the outcome was the same as the first try.
Am I missing something? How can I change the flip state AND update the check in the propertiesTable at the same time?
Any help would be very welcome.
Kind regards,
Hans
Private Shared Function SwitchVisualState(ByRef ref As BlockReference, DynBlockTableRowNumber As Integer, blnVisualParameters As Boolean) As BlockReference Dim doc As Document = Autodesk.AutoCAD.ApplicationServices.Application.DocumentManager.MdiActiveDocument Dim ed As Editor = doc.Editor Try Using tr As Transaction = doc.TransactionManager.StartTransaction If ref.IsDynamicBlock Then 'DynBlockTableRowNumber entered If Not DynBlockTableRowNumber = -999 Then Dim blockDef As BlockTableRecord = TryCast(tr.GetObject(ref.DynamicBlockTableRecord, OpenMode.ForRead), BlockTableRecord) 'Open the extension dictionary If blockDef.ExtensionDictionary.IsNull Then Return ref End If Dim extDic As DBDictionary = TryCast(tr.GetObject(blockDef.ExtensionDictionary, OpenMode.ForRead), DBDictionary) 'Receive data from PropertiesTable Dim graph As Autodesk.AutoCAD.Internal.DatabaseServices.EvalGraph = TryCast(tr.GetObject(extDic.GetAt("ACAD_ENHANCEDBLOCK"), OpenMode.ForRead), EvalGraph) Dim nodeIds As Integer() = graph.GetAllNodes() For Each nodeId As UInteger In nodeIds Dim node As DBObject = graph.GetNode(nodeId, OpenMode.ForRead, tr) If Not (TypeOf node Is BlockPropertiesTable) Then Continue For End If Dim table As BlockPropertiesTable = TryCast(node, BlockPropertiesTable) Dim currentRowIndex As Integer = DynBlockTableRowNumber Dim row As BlockPropertiesTableRow = table.Rows(currentRowIndex) Dim nameProps As New List(Of String)() For i As Integer = 0 To table.Columns.Count - 1 nameProps.Add(table.Columns(i).Parameter.Name) Next 'Set properties to dynamic block according to selected row ref.UpgradeOpen() Using newDynBlockRefPropColl As DynamicBlockReferencePropertyCollection = ref.DynamicBlockReferencePropertyCollection For Each DynBlockRefProp As DynamicBlockReferenceProperty In newDynBlockRefPropColl Dim strValues As String = "" For Each valueX In DynBlockRefProp.GetAllowedValues strValues &= valueX.ToString & ", " Next ' Debug.Print(DynBlockRefProp.PropertyName & ", Allowed values: " & strValues) Dim i As Integer = nameProps.FindIndex(Function(s As String) s = DynBlockRefProp.PropertyName) If i >= 0 AndAlso i < nameProps.Count Then Try If DynBlockRefProp.VisibleInCurrentVisibilityState = blnVisualParameters Then If Not DynBlockRefProp.Value = row(i).AsArray()(0).Value Then DynBlockRefProp.Value = row(i).AsArray()(0).Value 'Debug.Print(DynBlockRefProp.PropertyName & "=" & DynBlockRefProp.Value & "," & "column" & i & "=" & row(i).AsArray()(0).Value) End If End If Catch ed.WriteMessage(vbLf & "Can not set to {0} value={1}", DynBlockRefProp.PropertyName, row(i).AsArray()(0).Value) End Try Else End If Next End Using Next End If End If tr.Commit() End Using Return ref Catch ex As Exception MsgBox(ex.Message) Return Nothing End Try End Function
I can't tell from your code, is the flip value in "short" format?
My flip states won't accept anything but 0 or 1 in short format.
my $0.02
Yes, the flip state is in 'short' format, but is not visible in the lookup menu of the dynamic block. Instead, a dummy parameter in textformat "Left / Right" is presented to in the block (more userfriendly). Both parameters are defined as columns in the propertiesTable, so a row always contains the combination direction = Short(0) and text = "Left" or the combination direction = Short(1) and text = "Right" ...
Hi,
Creating a Lookup parameter can help in this case.
The "Not flipped" and "Flipped" states of the flip parameter can be mapped to "Left" and "Right" of the Lookup parameter.
In that case, switching from Left to Right in the Lookup parameter will automatically also flip.
I have attached a drawing to demonstrate this.
If you still need to use a property table for other reasons, I will test it and and let you know what I find.
I have seen in the past that some of the dynamic properties (for example, Visibility) does not reflect when set using AutoCAD .Net API while it worked ok in ObjectARX.
Regards,
Balaji
Hi Balaji,
Thanks for your reply, the way you've created your dynamic block is similar to mine, I make use of the Lookup parameter as well. The only difference is that my block has multiple parameters and therefore uses the propertiesTable (see attachment, highlighted parameters dutch names for Left/Right ).
But assuming that your block is representive for my problem, what I am trying to do (using AutoCAD .Net API indeed) is to insert the dynamic block by code and then set 'Flip state1' to "flipped" (= not default) and set 'Lookup1' = Right, updating both the visual state and the check in the Lookup Table.
In my case, when I set 'Lookup1' by code, the visual state is shown as its default state ( = left).
When I set 'Flip state1' to flipped, the visual state is updated, but then the check is still default (= left)
Does this problem occur in your case as well?
Do you know another way to trigger the update/ refresh the visualstate of the dynamic block? Or trigger selection function of the propertiesTable by Index maybe?
kind regards,
Hans
Hi Balaji,
Thanks for your reply, the way you've created your dynamic block is similar to mine, I make use of the Lookup parameter as well. The only difference is that my block has multiple parameters and therefore uses the propertiesTable (see attachment, highlighted parameters dutch names for Left/Right ).
But assuming that your block is representive for my problem, what I am trying to do (using AutoCAD .Net API indeed) is to insert the dynamic block by code and then set 'Flip state1' to "flipped" (= not default) and set 'Lookup1' = Right, updating both the visual state and the check in the Lookup Table.
In my case, when I set 'Lookup1' by code, the visual state is shown as its default state ( = left).
When I set 'Flip state1' to flipped, the visual state is updated, but then the check is still default (= left)
Does this problem occur in your case as well?
Do you know another way to trigger the update/ refresh the visualstate of the dynamic block? Or trigger selection function of the propertiesTable by Index maybe?
kind regards,
Hans
Hi Hans,
I do not see that behavior. Both the Lookup parameter and the flip state update correctly.
With the drawing that I attached earlier, I am using this code to update the lookup parameter. I have attached two screenshots that show the check mark in the lookup parameter after it was updated using this code snippet. Can you please try this at your end and see if it works ?
[CommandMethod("Test")] static public void TestMethod() { Document doc = Application.DocumentManager.MdiActiveDocument; Database db = doc.Database; Editor ed = doc.Editor; PromptEntityOptions peo = new PromptEntityOptions("\nSelect a dynamic block reference: "); peo.SetRejectMessage("\nMust be a block reference..."); peo.AddAllowedClass(typeof(BlockReference), true); PromptEntityResult per = ed.GetEntity(peo); if (per.Status != PromptStatus.OK) return; PromptIntegerResult pir = ed.GetInteger("Flip state to set (0 or 1)"); if (pir.Status != PromptStatus.OK) return; int state = pir.Value; using (Transaction trans = db.TransactionManager.StartOpenCloseTransaction()) { BlockReference br = (BlockReference)trans.GetObject(per.ObjectId, OpenMode.ForWrite); if (br.IsDynamicBlock) { DynamicBlockReferencePropertyCollection dynBrCol = br.DynamicBlockReferencePropertyCollection; foreach (DynamicBlockReferenceProperty dynBrPro in dynBrCol) { if (dynBrPro.PropertyName.Equals("Lookup1")) { Object[] allowedValues = dynBrPro.GetAllowedValues(); if(allowedValues.Length > 0 && state < allowedValues.Length) { dynBrPro.Value = allowedValues[state]; } } } } trans.Commit(); } }
About updating the dynamic block reference, you can try the code in this blog post, but I am not sure if that will help in your case.
Regards,
Balaji
Can't find what you're looking for? Ask the community or share your knowledge.