Florian
Florian

Reputation: 4728

How to set the Constant property AttributeReference?

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

Upvotes: 1

Views: 1742

Answers (2)

Maxence
Maxence

Reputation: 13314

You need to change the AttributeDefinition in the block table record (property Constant), not on the AttributeReference. This property is shared with all the AttributeReference.

From the docs:

AutoCAD itself never creates a constant AttributeReference object. AutoCAD creates the AttributeReference objects for each BlockReference based on the AttributeDefinition objects within the referenced BlockTableRecord. If a constant AttributeDefinition is encountered, then AutoCAD uses the AttributeDefinition itself instead of creating a matching AttributeReference.

Upvotes: 1

bjhuffine
bjhuffine

Reputation: 934

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();
            }
        }

Upvotes: 2

Related Questions