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

Reading XData Property

3 REPLIES 3
Reply
Message 1 of 4
LialAtArnold
1316 Views, 3 Replies

Reading XData Property

I am using the code below to obtain the XData attached to a layer. It works fine until it hits a layer that has no XData attached yet. Then it throws an "Object reference not set" error. I have tried everything I can think of with this.
Seems simple enough, but how do you determine the existence/or not of a property?

Database db = HostApplicationServices.WorkingDatabase;

try
{
//Open up a DWG database transaction
using (Transaction tran = db.TransactionManager.StartTransaction())
{
//Get a reference to the Layer table and open it up for reading
LayerTable layerTable = (LayerTable)tran.GetObject(db.LayerTableId, OpenMode.ForRead);

//Get an enumeration for the layers in the DWG database
SymbolTableEnumerator sysTabEnum = layerTable.GetEnumerator();

ResultBufferEnumerator resBufXData;

while (sysTabEnum.MoveNext() == true)
{
//Get the objectID off of the record
ObjectId objEntr = (ObjectId)sysTabEnum.Current;

//Open the record for reading
LayerTableRecord ltr = (LayerTableRecord)tran.GetObject(objEntr, OpenMode.ForRead);

//Check the layer name for PIDSYM
if (ltr.Name.Equals("PIDSYM"))
{

// If no XData is attached then this call throws an error!!!!!!!!!
resBufXData = ltr.XData.GetEnumerator();

//Cycle through the data records
while (resBufXData.MoveNext() == true)
{
//Get the Type code out of the record
String resBufType = resBufXData.Current.TypeCode.ToString();

//Only need the data attached to Type 1000
if (resBufType.Equals("1000"))
{
//Get the Facility value
assignedFacility = resBufXData.Current.Value.ToString();
}

} //End While
}
.........more code........
3 REPLIES 3
Message 2 of 4
Anonymous
in reply to: LialAtArnold

You should probably spend some time learning
to use C#, because your code clearly shows that
you haven't taken that basic step.

In C#, you use foreach() to iterate through collections.

You do not use GetEnumerator(), MoveNext(), and Current
to do that. You can read more about that in posts here.

If an object has no XData, then the XData property returns
null. If a variable is null, you can't use it, and the error you
get is what happens if you try to do that.

--
http://www.caddzone.com

AcadXTabs: MDI Document Tabs for AutoCAD 2009
Supporting AutoCAD 2000 through 2009

http://www.acadxtabs.com

Introducing AcadXTabs 2010:
http://www.caddzone.com/acadxtabs/AcadXTabs2010.htm


wrote in message
news:6139517@discussion.autodesk.com...
I am using the code below to obtain the XData attached to a layer. It works
fine until it hits a layer that has no XData attached yet. Then it throws an
"Object reference not set" error. I have tried everything I can think of
with this. Seems simple enough, but how do you determine the existence/or
not of a property? Database db = HostApplicationServices.WorkingDatabase;
try { //Open up a DWG database transaction using (Transaction tran =
db.TransactionManager.StartTransaction()) { //Get a reference to the Layer
table and open it up for reading LayerTable layerTable =
(LayerTable)tran.GetObject(db.LayerTableId, OpenMode.ForRead); //Get an
enumeration for the layers in the DWG database SymbolTableEnumerator
sysTabEnum = layerTable.GetEnumerator(); ResultBufferEnumerator resBufXData;
while (sysTabEnum.MoveNext() == true) { //Get the objectID off of the record
ObjectId objEntr = (ObjectId)sysTabEnum.Current; //Open the record for
reading LayerTableRecord ltr = (LayerTableRecord)tran.GetObject(objEntr,
OpenMode.ForRead); //Check the layer name for PIDSYM if
(ltr.Name.Equals("PIDSYM")) { // If no XData is attached then this call
throws an error!!!!!!!!! resBufXData = ltr.XData.GetEnumerator(); //Cycle
through the data records while (resBufXData.MoveNext() == true) { //Get the
Type code out of the record String resBufType =
resBufXData.Current.TypeCode.ToString(); //Only need the data attached to
Type 1000 if (resBufType.Equals("1000")) { //Get the Facility value
assignedFacility = resBufXData.Current.Value.ToString(); } } //End While }
.........more code........
Message 3 of 4
LialAtArnold
in reply to: LialAtArnold

Sorry for my ignorance. I am having to learn this on the job without any formal training.



I never post to these forums until and unless I have no other alternative as I am always

assumed to be some kind of lazy idiot because I cannot come up with an answer that

others seem to think is beyond simple.



I was told here that the XData was returned as a ResultBuffer and the only example code I could find indicated that ResultBuffers were handled with a ResultBufferEnumerator.

I also tried to resolve the:




ltr.XData.ToString();


ltr.XData.GetEnumertaor();

ltr.Xdata.Equals(null);



All down to a null object and none of it worked.
Message 4 of 4
Anonymous
in reply to: LialAtArnold

{quote}

I was told here that the XData was returned as a
ResultBuffer and the only example code I could
find indicated that ResultBuffers were handled
with a ResultBufferEnumerator.

{quote}

It's not only the ResultBuffer, pretty much all of
the code that iterates over other collections like
the layer table, uses GetEnumerator(), MoveNext().

Can we assume that you learned that more general
approach to processing collections from the same
source as the ResultBufferEnumerator example?

In any case, can you cite the source of the example
that uses ResultBufferEnumerator ?

Here's how to find the first DxfCode 1000 item in
an XData ResultBuffer. In this case, the code is only
interested in the first occurance, so it uses 'break' to
exit the foreach() loop once the item is found. If you
wanted to process multiple occurences, then you'd
remove the 'break', and process the entire collection.

This code also shows how to use GetXDataForApplication(),
which is actually the correct way to do what you're doing,
because you are most-likely only interested in xdata for a
specific xdata application name, rather than any xdata. So,
the XData property reference is replaced with a call to the
GetXDataForApplication() method, which requires you to
pass the registered application name ("myappid" is used
in the example - replace it with your xdata's appname):

{code}


LayerTableRecord myLayer = // assign to a layer table record.

ResultBuffer buffer = myLayer.GetXdataForApplication("myappid");

// check if the layer has XData:

if( buffer != null )
{
foreach( TypedValue tv in buffer )
{
if( tv.TypeCode == 1000 )
{
// This is an item of interest, so use it.

// if you only need the first occurence,
// then exit the foreach() loop:
break;
}
}
}

{code}

Again, if the object has no XData, the XData property
is null, so you simply have to test it first before you try
to use it.

Learning on the fly is generally more expensive than
upfront learning, if you include the time reuqired to
revise or completely rewrite buggy code, and what
that can ultimately cost the end-user if it gets that far.

--
http://www.caddzone.com

AcadXTabs: MDI Document Tabs for AutoCAD 2009
Supporting AutoCAD 2000 through 2009

http://www.acadxtabs.com

Introducing AcadXTabs 2010:
http://www.caddzone.com/acadxtabs/AcadXTabs2010.htm

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

Post to forums  

Autodesk DevCon in Munich May 28-29th


Autodesk Design & Make Report

”Boost