Update dynamic block with constraint parameter while command is still active

Update dynamic block with constraint parameter while command is still active

damyan_lyaskov
Contributor Contributor
1,211 Views
5 Replies
Message 1 of 6

Update dynamic block with constraint parameter while command is still active

damyan_lyaskov
Contributor
Contributor

Hello, 

I am trying to insert and update a block with a constrain parameter and see this change while the command is still active. Attached is the block "EL" that has constrain parameter "WIDTH" (default value of 8 which I would like to set in the command to 16 and update to the screen while the command is still active. I will have more code added at the end but wanted to have the block updated correctly.  The block is inserted with "WIDTH" set to 8, and only when the program is exited the "WIDTH" is set to 16. 

Thank you

using System;

using Autodesk.AutoCAD.ApplicationServices;
using Autodesk.AutoCAD.DatabaseServices;
using Autodesk.AutoCAD.EditorInput;
using Autodesk.AutoCAD.Geometry;
using Autodesk.AutoCAD.Runtime;

namespace ClassLibrary1
{

    public static class MyBlockReference
    {
        private static Document doc = Application.DocumentManager.MdiActiveDocument;

        public static BlockReference Insert(String name, Point3d point1)
        {
            try
            {
                using (Transaction trans = doc.Database.TransactionManager.StartTransaction())
                {
                    BlockTable bt = trans.GetObject(doc.Database.BlockTableId, OpenMode.ForRead) as BlockTable;
                    ObjectId objId = bt[name];
                    BlockTableRecord btr = trans.GetObject(objId, OpenMode.ForRead) as BlockTableRecord;

                    BlockReference br = new BlockReference(point1, objId);
                    br.SetDatabaseDefaults();

                    Matrix3d ucs = doc.Editor.CurrentUserCoordinateSystem;
                    br.TransformBy(ucs);

                    BlockTableRecord ms = trans.GetObject(bt[BlockTableRecord.ModelSpace], OpenMode.ForWrite) as BlockTableRecord;
                    ms.AppendEntity(br);
                    trans.AddNewlyCreatedDBObject(br, true);

                    trans.Commit();

                    return br;
                }
            }
            catch (System.Exception ex)
            {
                doc.Editor.WriteMessage(ex.ToString() + "\nError in BlockReference.Insert() function!\nBlock Reference is null!");
                return null;
            }
        }

        public static void SetParameter(BlockReference br, String parameterName, double num)
        {
            using (Transaction trans = doc.Database.TransactionManager.StartTransaction())
            {
                BlockReference br1 = trans.GetObject(br.ObjectId, OpenMode.ForWrite) as BlockReference;

                if (br1 != null && br1.IsDynamicBlock)
                {
                    DynamicBlockReferencePropertyCollection props = br1.DynamicBlockReferencePropertyCollection;
                    foreach (DynamicBlockReferenceProperty prop in props)
                    {
                        if (prop.PropertyName == parameterName && !prop.ReadOnly)
                        {
                            prop.Value = num;
                        }
                    }
                }

                trans.Commit();
            }
        }


        [CommandMethod("TestBlockFunctions")]
        public static void Test_Method()
        {
            PromptResult pr = doc.Editor.GetString("\nBlock name:");
            if (pr.Status == PromptStatus.OK)
            {

                PromptPointOptions ppo = new PromptPointOptions("\nBlock position:");

                PromptPointResult ppr = doc.Editor.GetPoint(ppo);

                if (ppr.Status == PromptStatus.OK)
                {

                    BlockReference br = MyBlockReference.Insert(pr.StringResult, ppr.Value);

                    if (br == null)
                    {
                        doc.Editor.WriteMessage("\nCommand aborted!");
                        return;
                    }

                    MyBlockReference.SetParameter(br, "WIDTH", 16);
                    // HERE I WOULD LIKE AUTOCAD TO VISUALLY UPDATE THE WIDTH OF THE BLOCK TO 16. NOT WHEN EXITING THIS METHOD.

                    // THIS IS ALL I FOUND ONLINE THAT WAS SUPPOSED TO HELP ME, AND DID NOT
                    doc.TransactionManager.EnableGraphicsFlush(true);
                    doc.TransactionManager.QueueForGraphicsFlush();
                    doc.TransactionManager.FlushGraphics();
                    Autodesk.AutoCAD.Internal.Utils.FlushGraphics();

                    doc.Editor.Regen();
                    doc.Editor.UpdateScreen();

                    ppo = new PromptPointOptions("\nHERE THE ELBOW NEEDED TO BE ALREADY 16 WIDE. \nCLICK AGAIN.");

                    ppr = doc.Editor.GetPoint(ppo);
                }
            }
        }
    }
} 
0 Likes
Accepted solutions (1)
1,212 Views
5 Replies
Replies (5)
Message 2 of 6

FRFR1426
Collaborator
Collaborator
Accepted solution

Use UpdateAnonymousBlocks() like this:

 

using (var tr = doc.Database.TransactionManager.StartTransaction())
{
    var dynamicBlockTableRecord = (BlockTableRecord)br.DynamicBlockTableRecord.GetObject(OpenMode.ForRead);
    dynamicBlockTableRecord.UpdateAnonymousBlocks();
    tr.Commit();
}
doc.TransactionManager.QueueForGraphicsFlush();
Maxence DELANNOY
Manager
Add-ins development for Autodesk software products
http://wiip.fr
Message 3 of 6

damyan_lyaskov
Contributor
Contributor

Thank you.  It worked.

0 Likes
Message 4 of 6

MGO-Norsyn
Advocate
Advocate

I have a similar problem, I have a dynamic block with parametric constraint which calculates arc length based on radius and angle, which I set within the command. The problem is that the geometry of the block updates only when I exit the command and I need the updated geometry right after I place the block, so I can continue working with it.

I have tried using the approach with UpdateAnonymousBlocks() method but it doesn't have any effect!

Please help! 😞

0 Likes
Message 5 of 6

FRFR1426
Collaborator
Collaborator

Editor.Regen() ?

Maxence DELANNOY
Manager
Add-ins development for Autodesk software products
http://wiip.fr
0 Likes
Message 6 of 6

MGO-Norsyn
Advocate
Advocate

Nope. Editor.Regen() doesn't work either.

I found a way though.

I was running a command placing blocks in a while loop asking user for insertion points.

The previous placed block wouldn't update its geometry until editor prompted for next point.

So this led me to think that the control (or what's it called) needs to return to editor before the autocad would force the geometry to update.

I tried all kinds of editor.Regen() and other stuff but it wouldn't work.

Then I tried to use:

Application.DocumentManager.MdiActiveDocument.Editor.Command("-PAN", new Point3d(), new Point3d());

 and this actually worked!

I guess this line of code emulates the user issuing a meaningless command, but in return forces Autocad to update parametric geometry.

The only drawback is that this pollutes the editor echo with useless feedback.