.NET
cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 

Dynamic block visual state update after changing "Properties Table" by code

6 REPLIES 6
Reply
Message 1 of 7
Anonymous
2196 Views, 6 Replies

Dynamic block visual state update after changing "Properties Table" by code

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 BooleanAs 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 BlockPropertiesTableThen
                            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

 

6 REPLIES 6
Message 2 of 7
Anonymous
in reply to: Anonymous

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

Message 3 of 7
Anonymous
in reply to: Anonymous

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" ...

Message 4 of 7
Balaji_Ram
in reply to: Anonymous

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



Balaji
Developer Technical Services
Autodesk Developer Network

Message 5 of 7
Anonymous
in reply to: Balaji_Ram

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

 

  

 

 

Message 6 of 7
Anonymous
in reply to: Anonymous

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

Message 7 of 7
Balaji_Ram
in reply to: Anonymous

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.

 

http://adndevblog.typepad.com/autocad/2012/09/updating-dimensions-associated-with-a-dynamic-block.ht...

 

Regards,

Balaji

 

 



Balaji
Developer Technical Services
Autodesk Developer Network

Can't find what you're looking for? Ask the community or share your knowledge.

Post to forums  

AutoCAD Inside the Factory


Autodesk Design & Make Report