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

Change Current Visibility of Dynamic Block

6 REPLIES 6
SOLVED
Reply
Message 1 of 7
bsaidiD4GJM
264 Views, 6 Replies

Change Current Visibility of Dynamic Block

I have this method that is supposed to change the current visibility of the dynamic block. It does change the selected visibility but the display of the block does not match the selected visibility, it's as if it doesn't regenerate the dynamic block so it matches the newly selected visibility.

Does anyone have a clue why?

Thank you in advance.

 

private static void _changeVisibility(BlockReference blockRef, string newVisibilityValue)
{
    DynamicBlockReferenceProperty property = blockRef.DynamicBlockReferencePropertyCollection.Cast<DynamicBlockReferenceProperty>()
        .FirstOrDefault(x => x.PropertyName == _visibilityAttributeName);

    property.Value = newVisibilityValue;
}

 

6 REPLIES 6
Message 2 of 7
norman.yuan
in reply to: bsaidiD4GJM

Is the method called in the scope of a transaction, in which the BlockReference parameter is opened? Is the transaction committed afterwards?

Norman Yuan

Drive CAD With Code

EESignature

Message 3 of 7
bsaidiD4GJM
in reply to: norman.yuan

Yes and yes.

Message 4 of 7
bsaidiD4GJM
in reply to: norman.yuan

What I noticed is that when I make the program change the visibiliy of only one dynamic block, it executes the task properly. But when I freeze/thaw many layers, then I loop through many dynamic blocks and change their visibility, some of them "choose" to not get displayed according to their current visibility.

 

After executing the code, the selected visibility is WZ12-16-22, but the drawing doesn't match the selected visibility:

bsaidiD4GJM_0-1716910187040.png

 

After reselecting manually the same visibility using the dropdown, the drawing now matches the selected visibility: 

bsaidiD4GJM_1-1716912194072.png

 

Message 5 of 7

Freezing or throwing layers within the process is going to require a Regen. You didn't mention that you were doing that initially. If you want to avoid a full regeneration, you can use Autodesk.AutoCAD.Internal.CoreLayerUtilities.RegenLayers() to regenerate the layers that were thawed. You can also try calling RecordGraphicsModified() on each BlockReference, and try calling the dynamic BlockTableRecord's UpdateAnonymousBlocks() method as well. You should also use a Transaction from the Document's TransactionManager rather than the Database's TransactionManager.

Message 6 of 7

After further investigation, I found out that when I remove the code (the lines after the comment "Delete Layer" in the attached code below) responsible for the deletion the layers that I freeze, the dynamic blocks are displayed properly, without the need of Regen.

 

When I put the layer deletion code back on and add the Regen layer functionnality, the dynamic blocks are NOT displayed according to the selected visibility.

 

If no one finds out what causes this problematic, my plan B is to freeze the layers, then change the visbilities, then delete the frozen layers. This would solve my issue.

 

private void _freezeAndDeleteLayer(Database db, string layerName, LayerTable layerTable, Transaction tr)
{
    if (!layerTable.Has(layerName))
    {
        return;
    }

    // Get the ObjectId of the layer
    ObjectId layerId = layerTable[layerName];

    // Open the layer table record for write
    LayerTableRecord layerTableRecord = tr.GetObject(layerId, OpenMode.ForWrite) as LayerTableRecord;

    if (layerTableRecord == null)
    {
        return;
    }

    // Freeze the layer
    layerTableRecord.IsFrozen = true;

    //Delete Layer
    layerTableRecord.IsLocked = false;
    var blockTable = (BlockTable)tr.GetObject(db.BlockTableId, OpenMode.ForRead);
    foreach (var btrId in blockTable)
    {
        var block = (BlockTableRecord)tr.GetObject(btrId, OpenMode.ForRead);
        foreach (var entId in block)
        {
            var ent = (Entity)tr.GetObject(entId, OpenMode.ForRead);
            if (ent.Layer == layerName)
            {
                ent.UpgradeOpen();
                ent.Erase();
            }
        }
    }

    layerTableRecord.Erase();
}

 

Message 7 of 7

Your code should probably not operate on Anonymous Dynamic blocks.

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

Post to forums  

Technology Administrators


Autodesk Design & Make Report