Edit a Block via C#

Edit a Block via C#

Anonymous
Not applicable
7,349 Views
28 Replies
Message 1 of 29

Edit a Block via C#

Anonymous
Not applicable

Hi community,

 

my job is to make an editor for blocks in C#. There should be a WPF-window were the user can see a list of blocks. He selects one and than he should see an overview about block attributes like insertionpoint, basepoint, rotation and scaling and he should be able to edit these attributes in this form. 

 

I know how i can populate a list of block names, but I fail at finding an opportunity to edit these attributes. 

I get the blocktablerecords, but then?

 

I am very, very new to Autocad, and I've googled the last five hours unsuccessfully for a solution which is suitable for my problem. 

 

Please help me, it is very urgent! 

 

Kind regards, 

Klaus

0 Likes
7,350 Views
28 Replies
Replies (28)
Message 2 of 29

Alfred.NESWADBA
Consultant
Consultant

Hi,

 

>> I get the blocktablerecords, but then?

Scan through the entities in the BlockTableRecord and find out which one is from type AttributeDefinition

 

- alfred -

------------------------------------------------------------------------------------
Alfred NESWADBA
ISH-Solutions GmbH / Ingenieur Studio HOLLAUS
www.ish-solutions.at ... blog.ish-solutions.at ... LinkedIn ... CDay 2026
------------------------------------------------------------------------------------

(not an Autodesk consultant)
0 Likes
Message 3 of 29

Anonymous
Not applicable

The only thing i've found with "AttributeDefinition" was

 

blocktablerecord.HasAttributeDefinitions,

 

but nothing with type "AttributeDefinition". Maybe I've missunderstood you?

0 Likes
Message 4 of 29

Alfred.NESWADBA
Consultant
Consultant

Hi,

 

go through each DBObject in the BlockTableRecord

verify if the current checked object is an AttributeDefintion, if it is one you have one (of may be more) AttributeDefinitions, take them for your handling you need to do with them.

 

Dim tTrAct As DatabaseServices.Transaction = Nothing 'set your tTrAct
Dim tBlTabRec As DatabaseServices.BlockTableRecord = Nothing 'set your tBlTabRec

'now scan through the objects in the BTR
For Each tObjID As DatabaseServices.ObjectId In tBlTabRec
  If (tObjID.IsValid) AndAlso (Not tObjID.IsErased) AndAlso (tObjID.ObjectClass.DxfName.ToUpper = "ATTDEF") Then
    'ok object is valid and it's a AttributeDefinition
    Dim tAttDef As DatabaseServices.AttributeDefinition = CType(tTrAct.GetObject(tObjID, DatabaseServices.OpenMode.ForRead), DatabaseServices.AttributeDefinition)
    'here you have your access to the AttributeDefinition-object
  End If
Next

 

- alfred -

------------------------------------------------------------------------------------
Alfred NESWADBA
ISH-Solutions GmbH / Ingenieur Studio HOLLAUS
www.ish-solutions.at ... blog.ish-solutions.at ... LinkedIn ... CDay 2026
------------------------------------------------------------------------------------

(not an Autodesk consultant)
0 Likes
Message 5 of 29

Anonymous
Not applicable

Okay, i try to translate this in C# and i hope I am successful with that. Smiley Wink

 

0 Likes
Message 6 of 29

Alfred.NESWADBA
Consultant
Consultant

Hi,

 

>> i try to translate

If you don't know it: that may help >>>translate c# vb<<<

 

- alfred -

------------------------------------------------------------------------------------
Alfred NESWADBA
ISH-Solutions GmbH / Ingenieur Studio HOLLAUS
www.ish-solutions.at ... blog.ish-solutions.at ... LinkedIn ... CDay 2026
------------------------------------------------------------------------------------

(not an Autodesk consultant)
0 Likes
Message 7 of 29

Anonymous
Not applicable

At 

if ((tObjID.IsValid) && (tObjID.IsErased == false) && (tObjID.ObjectClass.DxfName.ToUpper = "ATTDEF"))
{
     AttributeDefinition tAttDef = (AttributeDefinition)tTrAct.GetObject(tObjID, OpenMode.ForRead);
}

 

 I get an error:

 

Cannot assign to 'ToUpper' because it is a 'method group'.

Do you know a workaround?

0 Likes
Message 8 of 29

Alfred.NESWADBA
Consultant
Consultant

Hi,

 

you can erase the .ToUpper as it should not be necessary in that case, AutoCAD reports "ATTDEF" already in uppercase IMHO.

But I think you have to set double "=" in that statement for comparision in C#? So one equal-sign is missing and then .ToUpper should work also!

      tObjID.ObjectClass.DxfName.ToUpper == "ATTDEF"

 

- alfred -

------------------------------------------------------------------------------------
Alfred NESWADBA
ISH-Solutions GmbH / Ingenieur Studio HOLLAUS
www.ish-solutions.at ... blog.ish-solutions.at ... LinkedIn ... CDay 2026
------------------------------------------------------------------------------------

(not an Autodesk consultant)
0 Likes
Message 9 of 29

Anonymous
Not applicable

Yes, the second "=" helped, but it needed .ToUpper() to really work. 

 

Okay I look how far i get with that and I will come back to this thread if I have any further problems. 

 

Thank you very much!

0 Likes
Message 10 of 29

Anonymous
Not applicable

Further problems! 😞

 

I've tried to print out some attributes but nothing happened... Now I've debugged this code:

 

if ((tObjID.IsValid) && (tObjID.IsErased == false) && (tObjID.ObjectClass.DxfName.ToUpper() == "ATTDEF"))
{
     window.listBlockAttributes.Items.Add(tAttDef.Layer);
     window.listBlockAttributes.Items.Add(tAttDef.Rotation.ToString());
}

 and i realized that something is wrong with the last if (tObjID.ObjectClass... and so on). 

The Code passes the first two ifs but never the third one.

 

Can you help me again? 😉

 

The whole code of this method:

 

[CommandMethod("loadbe")]
        public static void LoadBe()
        {
            Window1 window = new Window1();
            Document doc = Application.DocumentManager.MdiActiveDocument;
            Database db = doc.Database;
            
            Transaction tr = db.TransactionManager.StartTransaction();
            List<String> blocks = new List<string>();
            using (tr)
            {
                window.listBlockAttributes.Items.Add("bin im using");
                BlockTable bt = (BlockTable)tr.GetObject(db.BlockTableId, OpenMode.ForRead);
                foreach (ObjectId objId in bt)
                {
                    BlockTableRecord btr = (BlockTableRecord)tr.GetObject(objId, OpenMode.ForRead);

                    foreach (ObjectId tObjID in btr)
                    {

                        if ((tObjID.IsValid) && (tObjID.IsErased == false) && (tObjID.ObjectClass.DxfName.ToUpper() == "ATTDEF"))
                        {
                            AttributeDefinition tAttDef = (AttributeDefinition)tr.GetObject(tObjID, OpenMode.ForRead);
                            window.listBlockAttributes.Items.Add(tAttDef.Layer);
                            window.listBlockAttributes.Items.Add(tAttDef.Rotation.ToString());
                        }
                    }
                    window.listBlocks.Items.Add(btr.Name);
                }
            }
            Autodesk.AutoCAD.ApplicationServices.Application.ShowModelessWindow(window);
        }

 Yeah, i know this code is not very useful, but i only wanted to know if there are any attributes which i can print out and I throw them in a list for now.

 

Kind Regards

Klaus

0 Likes
Message 11 of 29

Alfred.NESWADBA
Consultant
Consultant

Hi,

 

 

 

>> something is wrong with the last if (tObjID.ObjectClass... and so on). 

>> The Code passes the first two ifs but never the third one.

What AutoCAD-version do you have? And have you set LateBinding as allowed in your C#-project-settings?

The .DxfName did not exist from the beginning of AutoCAD & dotNET, it was added with AutoCAD 2010 I think (but I'm not sure about that, maybe a version earlier).

Anyway, if the property would not exist in your AutoCAD-version you should get an exception then ... do you see such when debugging?

 

>> listBlockAttributes

What type is this variable?

 

- alfred -

 

PS: "bin im using" deutet auf D oder A oder CH hin???

------------------------------------------------------------------------------------
Alfred NESWADBA
ISH-Solutions GmbH / Ingenieur Studio HOLLAUS
www.ish-solutions.at ... blog.ish-solutions.at ... LinkedIn ... CDay 2026
------------------------------------------------------------------------------------

(not an Autodesk consultant)
0 Likes
Message 12 of 29

Anonymous
Not applicable

Autocad-version 2012

Visual Studio 2010

 

Latebinding doesn't mean anything to me. Smiley Indifferent

 

And at debugging, i get no exception(?).

 

listBlockAttributes is a ListBox.

 

PS: Österreich 😉

0 Likes
Message 13 of 29

Alfred.NESWADBA
Consultant
Consultant

Hi,

 

without error-handling (and some checks like check for proxy, for xref, ...) this works with my drawings (having blocks with attributes) and AutoCAD 2010, 2011, 2012, 32bit and 64bit:

 

        [Autodesk.AutoCAD.Runtime.CommandMethod("ADESK_ListBlockAttdefs")]
        public void ADESK_ListBlockAttdefs()
        {
            string ResultStr = "";

            Document tAcadDoc = Autodesk.AutoCAD.ApplicationServices.Application.DocumentManager.MdiActiveDocument;

            using (Transaction tTrAct = tAcadDoc.TransactionManager.StartTransaction())
            {
                BlockTable tBlTab = tTrAct.GetObject(tAcadDoc.Database.BlockTableId, OpenMode.ForRead) as BlockTable;
                IEnumerator tBlTabEnum = tBlTab.GetEnumerator();
                while (tBlTabEnum.MoveNext())
                {
                    BlockTableRecord tBlTabRec =tTrAct.GetObject((ObjectId) tBlTabEnum.Current ,OpenMode.ForRead) as BlockTableRecord;
                    IEnumerator tBlTabRecEnum = tBlTabRec.GetEnumerator();
                    while (tBlTabRecEnum.MoveNext())
                    {
                        ObjectId tObjID = (ObjectId)tBlTabRecEnum.Current;
                        if ((tObjID.IsValid == true) && (tObjID.IsErased == false) && (tObjID.ObjectClass.DxfName.ToUpper() == "ATTDEF"))
                        {
                            AttributeDefinition tAttDef = tTrAct.GetObject(tObjID,OpenMode.ForRead) as AttributeDefinition;
                            ResultStr += "Block: " + tBlTabRec.Name + "... Att: " + tAttDef.Tag +  "\n\r";
                        }
                    }
                }
            }
            //here you have the result of all your Blockdefinitions and their Attributedefinitions
        }

 

 

- alfred -

------------------------------------------------------------------------------------
Alfred NESWADBA
ISH-Solutions GmbH / Ingenieur Studio HOLLAUS
www.ish-solutions.at ... blog.ish-solutions.at ... LinkedIn ... CDay 2026
------------------------------------------------------------------------------------

(not an Autodesk consultant)
0 Likes
Message 14 of 29

Anonymous
Not applicable

Okay, i've tried your solutioin a bit, but the compiler isn't able to get in this third if:

 

if(tObjID.ObjectClass.DxfName.ToUpper() == "ATTDEF")
{
    ...
}

 The value of tObjID.ObjectClass.DxfName.ToUpper() is always something like "LINE", "LWPOLYLINE", etc. but never "ATTDEF". 

Hmmm, and now?

0 Likes
Message 15 of 29

Alfred.NESWADBA
Consultant
Consultant

Hi,

 

can you upload a drawing that you work on for testing the code?

 

- alfred -

------------------------------------------------------------------------------------
Alfred NESWADBA
ISH-Solutions GmbH / Ingenieur Studio HOLLAUS
www.ish-solutions.at ... blog.ish-solutions.at ... LinkedIn ... CDay 2026
------------------------------------------------------------------------------------

(not an Autodesk consultant)
0 Likes
Message 16 of 29

Anonymous
Not applicable

Oh.. they are very simple! Smiley LOL

0 Likes
Message 17 of 29

Alfred.NESWADBA
Consultant
Consultant

Hi,

 

you don't have Attribtutes (not -definitions and no -references) in your drawing. So the scan will never find one as there are none. 😉

Try my attachment, a traffic-sign with a lot of attributes.

 

- alfred -

------------------------------------------------------------------------------------
Alfred NESWADBA
ISH-Solutions GmbH / Ingenieur Studio HOLLAUS
www.ish-solutions.at ... blog.ish-solutions.at ... LinkedIn ... CDay 2026
------------------------------------------------------------------------------------

(not an Autodesk consultant)
0 Likes
Message 18 of 29

Anonymous
Not applicable

Thanks for that, my Autocad-experiences belong to a 15min introduction. 😉

 

Okay, I've tried it and now I see a lot more than 10 minutes ago! 🙂

 

Next step: editting these attributes... We will see... 😉

0 Likes
Message 19 of 29

Alfred.NESWADBA
Consultant
Consultant

Hi,

 

>> Next step: editting these attributes

Be careful, you should understand some AutoCAD-internals to be able to develop based on it.

 

In this example you have to differenciate between AttributeDefinition and AttributeReference! If you want to modify the definition of the block, then you have to do this with BlockTableRecord and AttribtueDefinition, if you want to modify the speed-limit of my traffic-sign you have to use BlockReference and AttributeCollection and AttributeReference.


The example-code above handles the definitions.

 

- alfred -

------------------------------------------------------------------------------------
Alfred NESWADBA
ISH-Solutions GmbH / Ingenieur Studio HOLLAUS
www.ish-solutions.at ... blog.ish-solutions.at ... LinkedIn ... CDay 2026
------------------------------------------------------------------------------------

(not an Autodesk consultant)
0 Likes
Message 20 of 29

Anonymous
Not applicable

It should be generally able to edit these attributes:

 

- Layer

- Insertionpoint

- Basepoint

- Rotation

- Scaling X

- Scaling Y

- Scaling Z

- Sampling fraction (Auswahlsatz in Englisch? 😉 )

 

But this is the next problem, I see many attributes like kmh, beleuchtet, mast_id, etc. but non of those, I've mentioned.

How can i reach them?

0 Likes