Search code examples
c#autocadautocad-pluginobjectarx

How to set the Constant property AttributeReference?


Is it possible to change the Constant property of an AttributeReference ? (the property IsConstant is readonly)


Solution

  • I don't know about objectarx, but in .Net (since you stated c#), try this:

            Database currentDB = Application.DocumentManager.MdiActiveDocument.Database;
            using (Transaction transaction = currentDB.TransactionManager.StartTransaction())
            {
                BlockTable blockTable = (BlockTable)transaction.GetObject(currentDB.BlockTableId, OpenMode.ForRead);
    
                //Create the block if it doesn't exist
                if (!blockTable.Has("MyBlock"))
                {
                    using (BlockTableRecord myBlock = new BlockTableRecord())
                    {
                        myBlock.Name = "MyBlock";
                        myBlock.Origin = Point3d.Origin;
    
                        //You can add geometry here, but I'm just going to create the attribute
                        using (AttributeDefinition attribute = new AttributeDefinition())
                        {
                            attribute.Position = Point3d.Origin;
                            attribute.Tag = "Constant";
                            attribute.Prompt = "Enter value: ";
                            attribute.TextString = "My value";
                            attribute.Height = 0.5;
                            attribute.Justify = AttachmentPoint.BottomLeft;
                            attribute.Constant = true;
    
                            myBlock.AppendEntity(attribute);
    
                            //add to the block table
                            blockTable.UpgradeOpen();
                            blockTable.Add(myBlock);
                            transaction.AddNewlyCreatedDBObject(myBlock, true);
    
                        }
    
                    }
    
                    transaction.Commit();
                }
            }
    

    Edit: I just realized you also said AttributeReference and not AttributeDefinition. Without verifying for sure, I think the reference cannot be modified directly since the value is constant. Because of this, you'll have to update the block's definition in the BlockTableRecord, same basic process once you've got it.

    Here's the code for updating:

           Database currentDB = Application.DocumentManager.MdiActiveDocument.Database;
            using (Transaction transaction = currentDB.TransactionManager.StartTransaction())
            {
                BlockTable blockTable = (BlockTable)transaction.GetObject(currentDB.BlockTableId, OpenMode.ForRead);
    
    
                //Create the block if it doesn't exist
                if (blockTable.Has("MyBlock"))
                {
                    //Get the block
                    ObjectId myBlockID = blockTable["MyBlock"];
                    BlockTableRecord myBlock = (BlockTableRecord)transaction.GetObject(myBlockID, OpenMode.ForRead);
    
                    //iterate through objects and update the attribute definition
                    if (myBlock.HasAttributeDefinitions)
                    {
                        foreach (ObjectId oid in myBlock)
                        {
                            DBObject dbObject = transaction.GetObject(oid, OpenMode.ForRead);
                            if (dbObject is AttributeDefinition)
                            {
                                AttributeDefinition attribute = (AttributeDefinition)dbObject;
    
                                attribute.UpgradeOpen();
    
                                attribute.TextString = "NewValue";
                                attribute.Constant = true;
                            }
                        }
                    }
    
                    //Remember... BlockRerefences are glorified pointers to the BlockTableRecord that defines them
                    //so let's get all block references associated to it and update them
    
                    foreach (ObjectId oid in myBlock.GetBlockReferenceIds(false, true))
                    {
                        BlockReference blockReference = (BlockReference)transaction.GetObject(oid, OpenMode.ForWrite);
                        blockReference.RecordGraphicsModified(true);
                    }
    
                    transaction.Commit();
                }
            }