Hi everyone, I open this topic to ask you a question about using the DBDictionary for saving XRecord in the file.
In all the examples I've seen the XRecord is set by selecting an entity. So I ask you: is it possible to set an XRecord without attributing it to a specific entity and then set a "generic" XRecord?
Thanks a lot, bye.
Solved! Go to Solution.
Solved by _gile. Go to Solution.
Hi,
There are two kinds of DBDictionary : extension dictionaries which are linked to a DBObject (graphical entity or non-graphical object) and named dictionaries which are entries of the root dictionary : NamedObjectsDictionary.
You can add custom DBDictionary instances to the NamedObjectsDictionary.
The NamedObjectsDictionary is accessed through Database.NamedObjectsDictionaryId.
Here's a little example:
[CommandMethod("DICTSAMPLE")]
public static void DictionarySample()
{
var doc = Application.DocumentManager.MdiActiveDocument;
var db = doc.Database;
var ed = doc.Editor;
string dictName = "DICT_TEST";
string xrecName = "XrecordTest";
var data = new ResultBuffer(new TypedValue(1, "Foo"), new TypedValue(70, 42));
using (var tr = db.TransactionManager.StartTransaction())
{
var nod = (DBDictionary)tr.GetObject(db.NamedObjectsDictionaryId, OpenMode.ForRead);
DBDictionary dict;
if(nod.Contains(dictName))
{
dict = (DBDictionary)tr.GetObject(nod.GetAt(dictName), OpenMode.ForWrite);
ed.WriteMessage($"\nDictionary '{dictName}' already exists.");
}
else
{
nod.UpgradeOpen();
dict = new DBDictionary();
nod.SetAt(dictName, dict);
tr.AddNewlyCreatedDBObject(dict, true);
ed.WriteMessage($"\nDictionary '{dictName}' created.");
}
Xrecord xrec;
if (dict.Contains(xrecName))
{
xrec = (Xrecord)tr.GetObject(dict.GetAt(xrecName), OpenMode.ForWrite);
ed.WriteMessage($"\nXrecord '{xrecName}' already exists.");
}
else
{
xrec = new Xrecord();
dict.SetAt(xrecName, xrec);
tr.AddNewlyCreatedDBObject(xrec, true);
ed.WriteMessage($"\nXrecord '{xrecName}' created.");
}
xrec.Data = data;
tr.Commit();
}
}
Hi, thank you so much for your help.
I have tried your example and it works very well and I would like to take it one step further. So I ask you: knowing the name of the dictionary how can I retrieve the keys of the records and their values?
I tried this but I can only get the keys but I don't know how to get the values it contains.
private void Button6_Click(object sender, EventArgs e)
{
Editor ed = Application.DocumentManager.MdiActiveDocument.Editor;
using (Transaction tr = HostApplicationServices.WorkingDatabase.TransactionManager.StartTransaction())
{
DBDictionary nod = tr.GetObject(HostApplicationServices.WorkingDatabase.NamedObjectsDictionaryId, OpenMode.ForRead);
if (nod.Contains("DICT_TEST") == true)
{
foreach (DBDictionaryEntry de in nod)
{
if (de.Key == "DICT_TEST")
{
DBDictionary layoutDB = tr.GetObject(de.Value, OpenMode.ForRead);
foreach (DBDictionaryEntry lode in layoutDB)
ed.WriteMessage("xrecName: " + lode.Key.ToString());
}
}
}
}
}
Bye.
You have to keep in mind a DBDictionary might contain any type of DBObject, even DBDictionaries (NamedObjectsDictionary contains many DBDictionaries), not only Xrecords.
In you code you have to explicitly cast all DBObjects you open with Transaction.GetObject().
Here's an example:
var doc = Application.DocumentManager.MdiActiveDocument;
var db = doc.Database;
var ed = doc.Editor;
using (var tr = db.TransactionManager.StartTransaction())
{
var nod = (DBDictionary)tr.GetObject(db.NamedObjectsDictionaryId, OpenMode.ForRead);
if (nod.Contains("DICT_TEST"))
{
var dict = (DBDictionary)tr.GetObject(nod.GetAt("DICT_TEST"), OpenMode.ForRead);
foreach (DBDictionaryEntry de in dict)
{
string key = de.Key;
ObjectId id = de.Value;
ed.WriteMessage($"\nEntry key: {key} Entry type: {id.ObjectClass.Name}");
if (id.ObjectClass.DxfName == "XRECORD")
{
var xrec = (Xrecord)tr.GetObject(id, OpenMode.ForRead);
foreach (TypedValue tv in xrec.Data)
{
ed.WriteMessage($"\nValue: {tv.Value}");
}
}
}
}
}
Can't find what you're looking for? Ask the community or share your knowledge.