Let us look at a cool AutoCAD .NET coding gadget in this post, which can copy all good properties from an AutoCAD DBObject or Entity to another in case they are in the same kind.
In the old days without the reflection technology, this is quite a nasty task. We generally had to cast the AutoCAD generic object/entity to each available good type and access to its properties. Many short points are with this approach. The two most prominent are not efficient at all likely hundreds of even thousands of line of code have to be made and not compatible with old or new object models so likely some properties are missing in one version but some others are not available in another.
With the wonderful reflection technology handy, all these problems have gone away completely. We can make the same work done more nicely and professionally in just about a dozen lines of code:
public class CopyProperties
{
public static void BetweenSameKind(DBObject source, DBObject target)
{
if (source.GetType() != target.GetType())
throw new ArgumentException("Not of the same kind!");
PropertyInfo[] piArr = source.GetType().GetProperties(BindingFlags.Public | BindingFlags.Instance);
foreach (PropertyInfo pi in piArr)
{
if (pi.CanRead && pi.CanWrite)
{
try
{
pi.SetValue(target, pi.GetValue(source, null), null);
}
catch (System.Reflection.TargetInvocationException tiEx)
{
if (!(tiEx.InnerException is System.NotImplementedException))
{
Debug.WriteLine(tiEx.InnerException.Message); //ePlotStyleInColorDependentMode, etc.
}
}
}
}
}
public static void BetweenSameKind(ObjectId sourceId, ObjectId targetId)
{
if (sourceId.IsNull || targetId.IsNull || !sourceId.IsValid || !targetId.IsValid)
throw new ArgumentException();
using (Transaction tr = HostApplicationServices.WorkingDatabase.TransactionManager.StartTransaction())
{
DBObject source = tr.GetObject(sourceId, OpenMode.ForRead) as DBObject;
DBObject target = tr.GetObject(targetId, OpenMode.ForWrite) as DBObject;
BetweenSameKind(source, target);
tr.Commit();
}
}
}
As can be noticed, the NotApplicable or eNotApplicable case has also been taken care of in the succinct but cool coding gadget. For the sake of convenience, the command used to test it has been appended below:
[CommandMethod("TestCopyProperties")]
public static void TestCopyProperties_Method()
{
Editor ed = MgdAcApplication.DocumentManager.MdiActiveDocument.Editor;
Database db = HostApplicationServices.WorkingDatabase;
try
{
PromptEntityResult selRes = ed.GetEntity("\nPick the source object:");
if (selRes.Status == PromptStatus.OK)
{
PromptEntityResult selRes1 = ed.GetEntity("\nPick the target object:");
if (selRes1.Status == PromptStatus.OK)
{
CopyProperties.BetweenSameKind(selRes.ObjectId, selRes1.ObjectId);
}
}
}
catch (System.Exception ex)
{
ed.WriteMessage(ex.ToString());
}
}
If two circles are selected for example, the properties of the first one will be all copied over to the second including not only some general information like layer, color, linetype and line weight but also geometry properties like center, radius, normal and so on. Therefore, the second circle will look and behave almost exactly the same as the first one.
So, the code can be used to copy an AutoCAD Entity or DBObject without modifications or be tailored to suit other needs. Enjoy it! More coding gadgets will be created and demonstrated in the future. Please stay tuned.
The leading edge AutoCAD .NET Addin Wizard (AcadNetAddinWizard) provides various project wizards, item wizards, coders and widgets to help program AutoCAD .NET addins.
Posted by: |