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

BlockReference object: is it a dynamic block reference?

2 REPLIES 2
Reply
Message 1 of 3
norman.yuan
494 Views, 2 Replies

BlockReference object: is it a dynamic block reference?

I run into an interesting issue (well, it cost me quite a few hours in my current development project):

A BlockReference object, which is a Block reference generated from a dynamic block definition, can have its IsDynamic property either equal to True, or False. See this code snippet:

{code}

[CommandMethod("IsDyn")]
public static void GetDynamicBlockReference()
{
Document doc = Autodesk.AutoCAD.ApplicationServices.Application.DocumentManager.MdiActiveDocument;
Editor ed = doc.Editor;

PromptEntityOptions opt = new PromptEntityOptions("\nPick a dynamic block rference:");
opt.SetRejectMessage("\nYou must pick a block!");
opt.AllowNone = false;
opt.AddAllowedClass(typeof(BlockReference), true);

PromptEntityResult res = ed.GetEntity(opt);
if (res.Status != PromptStatus.OK) return;

BlockReference bref=null;

using (Transaction tran = doc.Database.TransactionManager.StartTransaction())
{
bref = tran.GetObject(res.ObjectId, OpenMode.ForRead) as BlockReference;

if (bref.IsDynamicBlock)
{
//This message will show, of course, if you picked dynamic block
MessageBox.Show("Within transaction scope: It is a dynamic block.");
}
else
{
MessageBox.Show("Within transaction scope: It is not a dynamic block.");
}
}

if (bref.IsDynamicBlock)
{
MessageBox.Show("Out of transaction scope: It is a dynamic block.");
}
else
{
//After leaving transaction, this message shows!!!
MessageBox.Show("Out of transaction scope: It is not a dynamic block.");
}
}

{/code}

If you run the code by picking a dynamic block in a drawing, you can see what I am trying to say here.

That is, when you obtain a BlockReference via a ObjectId, the BlockReference is indeed a dynamic while it is still in the scope of transaction. But once you are done with the transaction, you may still want to keep the BlockRefernce object for other purpose. However, as soon as the BlockRefernce leaves the transaction, it is no longer a dynamic block any more.

In my current Acad .NET program, I re-used existing code that retrieve a BlockRefernce from an ObjectId. Then in current program, I'd like use the BlockReference object to do something and eventually update its dynamic properties. But whenever I run the code, its dynamic properties are never updated. Each time I debug, I stoped in my re-used code because it shows clearly it is dynamic block. I eventually found out the BlockReference passed from my re0used code is not a dynamic block once it is out of the transaction, in which the BlockReferebce is generated by the transaction's GetObject() method. Actually, not only IsDynamic property changes from True to False, its DynamicBlockReferencePropertyCollection's Count property also changes from greater than 0 to 0.

I do not see anywhere this issue are mentioned/documented. It is certainly interesting, strange and confusing that an entity's property could change just because of crossing transaction boundary.

I use Acad Map 2009 and VS2008.

Has anyone already known this? Or may I have done something wrong?

Norman Yuan

Drive CAD With Code

EESignature

2 REPLIES 2
Message 2 of 3
norman.yuan
in reply to: norman.yuan

Let me retry the code, hope the format remains.

{code}

[CommandMethod("IsDyn")]
public static void GetDynamicBlockReference()
{
Document doc = Autodesk.AutoCAD.ApplicationServices.Application.DocumentManager.MdiActiveDocument;
Editor ed = doc.Editor;

PromptEntityOptions opt = new PromptEntityOptions("\nPick a dynamic block rference:");
opt.SetRejectMessage("\nYou must pick a block!");
opt.AllowNone = false;
opt.AddAllowedClass(typeof(BlockReference), true);

PromptEntityResult res = ed.GetEntity(opt);
if (res.Status != PromptStatus.OK) return;

BlockReference bref=null;

using (Transaction tran = doc.Database.TransactionManager.StartTransaction())
{
bref = tran.GetObject(res.ObjectId, OpenMode.ForRead) as BlockReference;

if (bref.IsDynamicBlock)
{
//This message will show, of course, if you picked dynamic block
MessageBox.Show("Within transaction scope: It is a dynamic block.");
}
else
{
MessageBox.Show("Within transaction scope: It is not a dynamic block.");
}
}

if (bref.IsDynamicBlock)
{
MessageBox.Show("Out of transaction scope: It is a dynamic block.");
}
else
{
//After leaving transaction, this message shows!!!
MessageBox.Show("Out of transaction scope: It is not a dynamic block.");
}
}

{code}

Norman Yuan

Drive CAD With Code

EESignature

Message 3 of 3
Anonymous
in reply to: norman.yuan

I think I've mentioned more than a few times here, that a DBObject that was
obtained from a transaction is only guaranteed to be valid up to the point
when the transaction it was obtained from has ended (the native ObjectARX
docs specifically say that).

In the case of most read-only access, a DBObject will continue to work after
the transaction it was opened in has ended, but as you've just discovered,
there are exceptions, this being one. Getting the properties of a dynamic
block refrerence is another.

You should design your code to avoid using a DBObject outside of the
transaction you got it from. It's just not a good idea. If you need to
subsequently reference a DBObject, cache its id and open it when needed.

--
http://www.caddzone.com

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

http://www.acadxtabs.com

Email: string.Format("{0}@{1}.com", "tonyt", "caddzone");

wrote in message news:6246452@discussion.autodesk.com...
I run into an interesting issue (well, it cost me quite a few hours in my
current development project):

A BlockReference object, which is a Block reference generated from a dynamic
block definition, can have its IsDynamic property either equal to True, or
False. See this code snippet:

{code}

[CommandMethod("IsDyn")]
public static void GetDynamicBlockReference()
{
Document doc =
Autodesk.AutoCAD.ApplicationServices.Application.DocumentManager.MdiActiveDocument;
Editor ed = doc.Editor;

PromptEntityOptions opt = new PromptEntityOptions("\nPick a
dynamic block rference:");
opt.SetRejectMessage("\nYou must pick a block!");
opt.AllowNone = false;
opt.AddAllowedClass(typeof(BlockReference), true);

PromptEntityResult res = ed.GetEntity(opt);
if (res.Status != PromptStatus.OK) return;

BlockReference bref=null;

using (Transaction tran =
doc.Database.TransactionManager.StartTransaction())
{
bref = tran.GetObject(res.ObjectId, OpenMode.ForRead) as
BlockReference;

if (bref.IsDynamicBlock)
{
//This message will show, of course, if you picked
dynamic block
MessageBox.Show("Within transaction scope: It is a
dynamic block.");
}
else
{
MessageBox.Show("Within transaction scope: It is not a
dynamic block.");
}
}

if (bref.IsDynamicBlock)
{
MessageBox.Show("Out of transaction scope: It is a dynamic
block.");
}
else
{
//After leaving transaction, this message shows!!!
MessageBox.Show("Out of transaction scope: It is not a
dynamic block.");
}
}

{/code}

If you run the code by picking a dynamic block in a drawing, you can see
what I am trying to say here.

That is, when you obtain a BlockReference via a ObjectId, the BlockReference
is indeed a dynamic while it is still in the scope of transaction. But once
you are done with the transaction, you may still want to keep the
BlockRefernce object for other purpose. However, as soon as the
BlockRefernce leaves the transaction, it is no longer a dynamic block any
more.

In my current Acad .NET program, I re-used existing code that retrieve a
BlockRefernce from an ObjectId. Then in current program, I'd like use the
BlockReference object to do something and eventually update its dynamic
properties. But whenever I run the code, its dynamic properties are never
updated. Each time I debug, I stoped in my re-used code because it shows
clearly it is dynamic block. I eventually found out the BlockReference
passed from my re0used code is not a dynamic block once it is out of the
transaction, in which the BlockReferebce is generated by the transaction's
GetObject() method. Actually, not only IsDynamic property changes from True
to False, its DynamicBlockReferencePropertyCollection's Count property also
changes from greater than 0 to 0.

I do not see anywhere this issue are mentioned/documented. It is certainly
interesting, strange and confusing that an entity's property could change
just because of crossing transaction boundary.

I use Acad Map 2009 and VS2008.

Has anyone already known this? Or may I have done something wrong?

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