Issue With Attribute Visibility

My_Civil_3D
Advocate
Advocate

Issue With Attribute Visibility

My_Civil_3D
Advocate
Advocate

Hi Guys i am having a weird problem With a Blocks Attribute. 

at default a Certain Attribute is not visible because of the field being blank. i have a program with a checkbox to make the Attribute Visible. This seems to work fine only when the Battman command has been used on that drawing before, otherwise the checkbox doesn't work and does not activate the visibility state of that attribute. this is strange i am not sure if there is a system variable that also has to be changed. can someone please give some input?

Here is a snip of my code:

Class:
    private void SetAttributeVisibility(Transaction tr, BlockReference blockRef, string attributeName, bool isVisible)
    {
        foreach (ObjectId attId in blockRef.AttributeCollection)
        {
            AttributeReference attRef = tr.GetObject(attId, OpenMode.ForWrite) as AttributeReference;
            if (attRef != null && attRef.Tag == attributeName)
            {
                attRef.Visible = isVisible;
                break;
            }
        }
    }

 

  public void HandleCheckboxVisibility(CheckBox checkBox, params string[] attributeNames)
  {
      // Get the visibility state based on the checkbox checked status
      bool isVisible = checkBox.Checked;

      Document doc = Application.DocumentManager.MdiActiveDocument;
      Database db = doc.Database;
      Editor ed = doc.Editor;

      using (DocumentLock docLock = doc.LockDocument())
      {
          using (Transaction tr = db.TransactionManager.StartTransaction())
          {
              BlockTable bt = tr.GetObject(db.BlockTableId, OpenMode.ForRead) as BlockTable;
              if (bt != null)
              {
                  BlockTableRecord layout = tr.GetObject(bt[BlockTableRecord.PaperSpace], OpenMode.ForRead) as BlockTableRecord;
                  if (layout != null)
                  {
                      foreach (ObjectId objId in layout)
                      {
                          if (objId.ObjectClass.Name == "AcDbBlockReference")
                          {
                              BlockReference blockRef = tr.GetObject(objId, OpenMode.ForWrite) as BlockReference;
                              if (blockRef != null && blockRef.Name == BlockName)
                              {
                                  foreach (string attributeName in attributeNames)
                                  {
                                      SetAttributeVisibility(tr, blockRef, attributeName, isVisible);
                                  }
                              }
                          }
                      }
                  }
                  else
                  {
                      MessageBox.Show("The Titleblock is not loaded. Please ensure the Titleblock is loaded and try again.", "Titleblock Not Loaded", MessageBoxButtons.OK, MessageBoxIcon.Warning);
                      return;
                  }
              }
          }
      }
Civil 3D Certified Professional
0 Likes
Reply
973 Views
18 Replies
Replies (18)

Anton_Huizinga
Advocate
Advocate

I don't see a Transaction Commit, does that change anything?

0 Likes

My_Civil_3D
Advocate
Advocate

you are right sometimes it needs another eye lol let me fix and retry/thanks though

Civil 3D Certified Professional
0 Likes

My_Civil_3D
Advocate
Advocate

Fixed the trans.commit error i made. still the same. its weird how it doesnt want to work untill the visibility has ben changed in the "battman" command and after that it works without any issues. i am stumped at this point and have no idea what to look at next

Civil 3D Certified Professional
0 Likes

_gile
Mentor
Mentor

Hi,

In the code you post, you use the Entity.Visible property, not the specific AttributeReference.Invisible one.



Gilles Chanteau
Programmation AutoCAD LISP/.NET
GileCAD
GitHub

0 Likes

My_Civil_3D
Advocate
Advocate

i have fix and updated the code. does exactly the same thing. this is really weird for me. does the "Battman command" maybe change some variable that i also need to change in the code?

Civil 3D Certified Professional
0 Likes

_gile
Mentor
Mentor

This works for me:

private static void SetAttributeVisibility(Transaction tr, BlockReference blockRef, string attributeName, bool isVisible)
{
    foreach (ObjectId attId in blockRef.AttributeCollection)
    {
        AttributeReference attRef = (AttributeReference)tr.GetObject(attId, OpenMode.ForWrite);
        if (attRef.Tag.Equals(attributeName, StringComparison.OrdinalIgnoreCase))
        {
            attRef.Invisible = !isVisible;
            break;
        }
    }
}

 

Take care, in the HandleCheckboxVisibility method you show, doing:

BlockTableRecord layout = tr.GetObject(bt[BlockTableRecord.PaperSpace], OpenMode.ForRead) as BlockTableRecord;

only gets the last opened layout block table record.

 

Another thing, it the block you're looking from is a dynamic block, it may be "anonymous". In this case, you should replace:

if (blockRef != null && blockRef.Name == BlockName)
{
    foreach (string attributeName in attributeNames)
    {
        SetAttributeVisibility(tr, blockRef, attributeName, isVisible);
    }
}

with:

BlockTableRecord dynamicBtr = (BlockTableRecord)tr.GetObject(blockRef.DynamicBlockTableRecord, OpenMode.ForRead);
string effectiveName = dynamicBtr.Name;
if (effectiveName.Equals(BlockName, StringComparison.OrdinalIgnoreCase))
{
    foreach (string attributeName in attributeNames)
    {
        SetAttributeVisibility(tr, blockRef, attributeName, isVisible);
    }
}


Gilles Chanteau
Programmation AutoCAD LISP/.NET
GileCAD
GitHub

0 Likes

_gile
Mentor
Mentor

This method processes each block reference named "BlockName" (or anonymous block references issued from "BlockName") in every paper space layouts.

 

private void SetAttributeVisibility(Transaction tr, BlockReference blockRef, string attributeName, bool isVisible)
{
    foreach (ObjectId attId in blockRef.AttributeCollection)
    {
        AttributeReference attRef = (AttributeReference)tr.GetObject(attId, OpenMode.ForWrite);
        if (attRef.Tag.Equals(attributeName, StringComparison.OrdinalIgnoreCase))
        {
            attRef.Invisible = !isVisible;
            break;
        }
    }
}

public void HandleCheckboxVisibility(CheckBox checkBox, params string[] attributeNames)
{
    // Get the visibility state based on the checkbox checked status
    bool isVisible = checkBox.Checked;

    Document doc = Application.DocumentManager.MdiActiveDocument;
    Database db = doc.Database;

    using (doc.LockDocument())
    using (Transaction tr = db.TransactionManager.StartTransaction())
    {
        BlockTable bt = (BlockTable)tr.GetObject(db.BlockTableId, OpenMode.ForRead);
        if (bt.Has(BlockName))
        {
            BlockTableRecord blockDefinition = (BlockTableRecord)tr.GetObject(bt[BlockName], OpenMode.ForRead);
            foreach (ObjectId brId in blockDefinition.GetBlockReferenceIds(true, false))
            {
                BlockReference blockRef = (BlockReference)tr.GetObject(brId, OpenMode.ForWrite);
                BlockTableRecord owner = (BlockTableRecord)tr.GetObject(blockRef.OwnerId, OpenMode.ForRead);
                if (owner.Name.StartsWith("*Paper_Space"))
                {
                    foreach (string attributeName in attributeNames)
                    {
                        SetAttributeVisibility(tr, blockRef, attributeName, isVisible);
                    }
                }

                // Look for anonymous blocks
                foreach (ObjectId anonymousBlockId in blockDefinition.GetAnonymousBlockIds())
                {
                    BlockTableRecord anonymousBlock = (BlockTableRecord)tr.GetObject(anonymousBlockId, OpenMode.ForRead);
                    foreach (ObjectId anonymousBrId in anonymousBlock.GetBlockReferenceIds(true, false))
                    {
                        blockRef = (BlockReference)tr.GetObject(anonymousBrId, OpenMode.ForWrite);
                        owner = (BlockTableRecord)tr.GetObject(blockRef.OwnerId, OpenMode.ForRead);
                        if (owner.Name.StartsWith("*Paper_Space"))
                        {
                            foreach (string attributeName in attributeNames)
                            {
                                SetAttributeVisibility(tr, blockRef, attributeName, isVisible);
                            }
                        }
                    }
                }
            }
        }
        else
        {
            MessageBox.Show("The Titleblock is not loaded. Please ensure the Titleblock is loaded and try again.", "Titleblock Not Loaded", MessageBoxButtons.OK, MessageBoxIcon.Warning);
            return;
        }
        tr.Commit();
    }
}

 



Gilles Chanteau
Programmation AutoCAD LISP/.NET
GileCAD
GitHub

0 Likes

My_Civil_3D
Advocate
Advocate

I have made the changes but it still does the same thing. If i take 2 drawings. 1 where i quickly set the visibility mode in the battman comand and then run the code it works without issues.

 

But as soon as i open a drawing where the battman command was not run before hand it doesnt work.

 

What can cause this? 

 

Civil 3D Certified Professional
0 Likes

_gile
Mentor
Mentor

The BATTMAN command changes the Invisible property of the AttributeDefinition in the block definition (BlockTableRecord) and synchronizes the attribute references.

The "SetAttributeVisibility" method called by "HandleCheckboxVisibility" changes the Invisible property of the attribute reference of the block reference found in the paper space layout only.



Gilles Chanteau
Programmation AutoCAD LISP/.NET
GileCAD
GitHub

0 Likes

My_Civil_3D
Advocate
Advocate

Sorry i am not following. The block it needs to edit is only in paperspace its a titleblock. Thats why i only set it for the block in paperspace. This is interesting im.learning allot from this.

Civil 3D Certified Professional
0 Likes

_gile
Mentor
Mentor

Did you try the code I posted reply #8 ?



Gilles Chanteau
Programmation AutoCAD LISP/.NET
GileCAD
GitHub

0 Likes

My_Civil_3D
Advocate
Advocate

yes i did can i maybe send you the 2 drawings for example so you can check your side? will also give you the coding?

Civil 3D Certified Professional
0 Likes

_gile
Mentor
Mentor

For sure, attach the drawings.



Gilles Chanteau
Programmation AutoCAD LISP/.NET
GileCAD
GitHub

0 Likes

My_Civil_3D
Advocate
Advocate

can you maybe send me your email adress in pvt message. the drawings contain persona company info which i dont just want to share here.

Civil 3D Certified Professional
0 Likes

_gile
Mentor
Mentor

I do not want to make private personal assistance. I'm on this forum to share with everyone.

You should be able to make some relevant sample drawing without confidential information.



Gilles Chanteau
Programmation AutoCAD LISP/.NET
GileCAD
GitHub

0 Likes

My_Civil_3D
Advocate
Advocate

this issue only occurs in certain drawings i cant just recreate the issue. and i also cant share my companies' drawings online due to security, you have to also understand that. if you are unable to look at the drawings privately i also understand. 

Civil 3D Certified Professional
0 Likes

_gile
Mentor
Mentor

@My_Civil_3D wrote:

this issue only occurs in certain drawings


This means the issue is due to the drawing, not to the code.

So you should check these drawings (AUDIT), and more specifically the block the issue occurs on

 



Gilles Chanteau
Programmation AutoCAD LISP/.NET
GileCAD
GitHub

0 Likes

My_Civil_3D
Advocate
Advocate

I have looked at the Drawing and block itself and i cant see m to find if there is an issue somewhere. i have attached the Working and Not Working Block. The issue is with the Hold List & Remarks not showing correctly in all drawings when the show hold is ticked. Here is the Dwg's and the Code. @_gile  as you requested hopefully you can point out the issues

Civil 3D Certified Professional
0 Likes