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

Best way to associate data with a DBEntity?

5 REPLIES 5
Reply
Message 1 of 6
nshupeFMPE3
487 Views, 5 Replies

Best way to associate data with a DBEntity?

Part of our process is to select lines to represent a zone. The tools should be able to prompt the user to select a line and change its color and assign it values such as a zone number. 

What is the best way to add this data into the drawing for later use by the tool? Should I use Xdata on the objects? Or an Xrecord? Or add to the NOD? 

 

I've heard of all of these things but I'm not clear on what the difference between them are, or how to do them

Labels (3)
5 REPLIES 5
Message 2 of 6
_gile
in reply to: nshupeFMPE3

Hi,

You can use either xdata or xrecord in the extension dictionary of the entity.

Xdata is limited to a small amount of data per object (16 ko) and you need to share this small amount with all the other applications that use it.

Xrecords may be of arbitrary length and there may be many xrecords per entity.

 

 

 



Gilles Chanteau
Programmation AutoCAD LISP/.NET
GileCAD
GitHub

Message 3 of 6
nshupeFMPE3
in reply to: _gile

Where would a resource be that explains how to do the whole XRecord process. I'm having a hard time finding one. I wish it was in the Developer Guide

Message 4 of 6
_gile
in reply to: nshupeFMPE3

Here're some extension methods.

    public static class Extension
    {
        static class Assert
        {
            public static void IsNotNull<T>(T obj, string paramName) where T : class
            {
                if (obj == null)
                    throw new ArgumentNullException(paramName);
            }
        }

        public static Transaction GetTopTransaction(this Database db)
        {
            Assert.IsNotNull(db, nameof(db));
            return db.TransactionManager.TopTransaction ??
            throw new AcRx.Exception(ErrorStatus.NoActiveTransactions);
        }

        public static DBDictionary TryGetExtensionDictionary(this DBObject source)
        {
            Assert.IsNotNull(source, nameof(source));
            var tr = source.Database.GetTopTransaction();
            ObjectId dictId = source.ExtensionDictionary;
            if (dictId.IsNull)
            {
                return null;
            }
            return (DBDictionary)tr.GetObject(dictId, OpenMode.ForRead);
        }

        public static DBDictionary GetOrCreateExtensionDictionary(this DBObject source)
        {
            Assert.IsNotNull(source, nameof(source));
            var tr = source.Database.GetTopTransaction();
            if (source.ExtensionDictionary == ObjectId.Null)
            {
                source.UpgradeOpen();
                source.CreateExtensionDictionary();
            }
            return (DBDictionary)tr.GetObject(source.ExtensionDictionary, OpenMode.ForRead);
        }

        public static ResultBuffer GetXrecordData(this DBObject source, string key)
        {
            Assert.IsNotNull(source, nameof(source));
            var tr = source.Database.GetTopTransaction();
            DBDictionary dict;
            if (source is DBDictionary)
            {
                dict = (DBDictionary)source;
            }
            else
            {
                dict = source.TryGetExtensionDictionary();
                if (dict == null)
                    return null;
            }
            if (!dict.Contains(key))
            {
                return null;
            }
            var xrec = tr.GetObject(dict.GetAt(key), OpenMode.ForRead) as Xrecord;
            if (xrec == null)
            {
                return null;
            }
            return xrec.Data;
        }

        public static void SetXrecordData(this DBObject source, string key, ResultBuffer data)
        {
            Assert.IsNotNull(source, nameof(source));
            var tr = source.Database.GetTopTransaction();
            DBDictionary dict;
            if (source is DBDictionary)
            {
                dict = (DBDictionary)source;
            }
            else
            {
                dict = source.GetOrCreateExtensionDictionary();
            }
            Xrecord xrec;
            if (dict.Contains(key))
            {
                xrec = tr.GetObject(dict.GetAt(key), OpenMode.ForWrite) as Xrecord;
                if (xrec == null)
                {
                    throw new AcRx.Exception(ErrorStatus.InvalidKey, key);
                }
            }
            else
            {
                dict.UpgradeOpen();
                xrec = new Xrecord();
                dict.SetAt(key, xrec);
                tr.AddNewlyCreatedDBObject(xrec, true);
            }
            xrec.Data = data;
        }
    }


Gilles Chanteau
Programmation AutoCAD LISP/.NET
GileCAD
GitHub

Message 5 of 6
nshupeFMPE3
in reply to: nshupeFMPE3

Thank you once again! This is really helpful. I do have a couple follow up questions.
I'm confused by creating a ResultBuffer(). When I see people do it it is usually in conjunction with TypedValue and in the legacy code I have there are Dxf Codes?
Also what do I do with a ResultBuffer once I have gotten it from GetXRecordData()?
The legacy code I have does really weird things with BinaryFormatter's and MemoryStreams?
Is there a simpler way?

Message 6 of 6
_gile
in reply to: nshupeFMPE3

A Resultbuffer is mainly a TypedValue collection. This is a convinient way to store data of various types.

A TypedValue is like a pair containing a TypeCode and a Value of corresponding type.

The TypedValue.TypeCode is a short which can also be expressed with enums as DxfCode (or LispDataType).



Gilles Chanteau
Programmation AutoCAD LISP/.NET
GileCAD
GitHub

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

Post to forums  

Forma Design Contest


Autodesk Design & Make Report