Hi Rick,
There is a known issue with the .Net API concerning not updating the block automatically after modifying the dynamic properties.
Here is a workaround I was providing for a similar previous request, unfortunatly it involves invoking some ObjectARX code:
A possible solution would be to modify the property using the same .net code that you provided and rely on an external function imported from an ARX module that will “refresh” the dynamic block reference properties. You don’t need to actually load the arx module in order to get it working, you just have to reference the *.arx dll on your disk.
Here is the arx code I have to refresh the block properties:
void RefreshDynamicBlkProperty(AcDbObjectId blockRefId)
{
AcDbEntity* pEnt = NULL;
if (acdbOpenObject(pEnt, blockRefId , AcDb::kForRead) != Acad::eOk)
{
acutPrintf(L"\nError opening entity.");
if(pEnt) pEnt->close();
return;
}
AcDbBlockReference *pBlkRef = AcDbBlockReference::cast(pEnt);
// initialise a AcDbDynBlockReference from the object id of the blockreference
AcDbDynBlockReference* pDynBlkRef = new AcDbDynBlockReference(pBlkRef->objectId());
//Don't forget to close the blockreference here,
//otherwise you wont be able to modify properties
pEnt->close();
if (pDynBlkRef)
{
AcDbDynBlockReferencePropertyArray blkPropAry;
pDynBlkRef->getBlockProperties(blkPropAry);
Acad::ErrorStatus err;
AcDbDynBlockReferenceProperty blkProp;
for(long lIndex1=0L ; lIndex1<blkPropAry.length() ; ++lIndex1)
{
blkProp = blkPropAry[lIndex1];
AcDbEvalVariant value = blkProp.value();
if(!blkProp.readOnly())
{
if((err = blkProp.setValue(value)) != Acad::eOk)
{
acutPrintf(L"\nError setting property value...");
}
}
}
//Don't forget to delete this reference, otherwise you will have problems.
delete pDynBlkRef;
}
}
Last thing you need to do on the arx side is to export this method. To do that you have to declare in one of the header (StdAfx.h for example) the following export:
extern "C" void _declspec(dllexport) RefreshDynamicBlkProperty(AcDbObjectId blockRefId);
And add to your arx project a .def file that looks like this:
LIBRARY "asdkArxMain"
EXPORTS RefreshDynamicBlkProperty
You just need to import this method in your .net dll and call it at the end of your command as follow:
const string arxPath = "C:\\My Documents\\AutoCAD\\ARX\\asdkArxMain.arx";
[DllImport(arxPath,
CharSet = CharSet.Unicode,
CallingConvention = CallingConvention.Cdecl,
EntryPoint = "RefreshDynamicBlkProperty")]
private static extern void RefreshDynamicBlkProperty(ObjectId blockRefId);
[CommandMethod("SetDynamicBlkProperty")]
static public void SetDynamicBlkProperty()
{
Document doc = Application.DocumentManager.MdiActiveDocument;
Editor ed = doc.Editor;
PromptEntityOptions peo = new PromptEntityOptions("Select a dynamic block reference...");
peo.SetRejectMessage("\nMust be a block reference...");
peo.AddAllowedClass(typeof(BlockReference), true);
PromptEntityResult per = ed.GetEntity(peo);
if (per.Status != PromptStatus.OK)
return;
using (Transaction Tx = doc.TransactionManager.StartTransaction())
{
BlockReference oBlkRef = Tx.GetObject(per.ObjectId, OpenMode.ForWrite) as BlockReference;
if (oBlkRef.IsDynamicBlock)
{
DynamicBlockReferencePropertyCollection oProperties = oBlkRef.DynamicBlockReferencePropertyCollection;
BlockTableRecord oBtr = Tx.GetObject(oBlkRef.BlockTableRecord, OpenMode.ForRead) as BlockTableRecord;
ed.WriteMessage("\nBlock Record: " + oBtr.Name + "\n");
foreach (DynamicBlockReferenceProperty oProp in oProperties)
{
object[] values = oProp.GetAllowedValues();
ed.WriteMessage("\n - PropertyName: " + oProp.PropertyName + " UnitsType: " + oProp.UnitsType.ToString());
for (int i = 0; i < values.Length; ++i)
{
ed.WriteMessage("\n . Value[" + i.ToString() + "]: " + values[i].ToString());
}
if (oProp.PropertyName == "Origin")
{
Point3d origin = (Point3d)oProp.Value;
ed.WriteMessage("\n . Origin: " + origin.ToString());
Point3d originWCS = origin.TransformBy(oBlkRef.BlockTransform);
ed.WriteMessage("\n . Origin WCS: " + originWCS.ToString());
}
//Switch Property
if (oProp.PropertyName == "Visibility" && !oProp.ReadOnly)
{
if (oProp.Value.ToString() == values[0].ToString()) oProp.Value = values[1];
else oProp.Value = values[0];
}
if (oProp.PropertyName == "Angle" && !oProp.ReadOnly)
{
oProp.Value = 10.0 * 3.1416 / 180.0;
}
}
}
Tx.Commit();
RefreshDynamicBlkProperty(oBlkRef.Id);
}
}
Philippe Leefsma
Developer Technical Services
Autodesk Developer Network