Autocad C# - 在撤消时,对象Xdata变为null

时间:2015-07-24 16:35:11

标签: c# autocad autocad-plugin

这是在AutoCAD 2016中

我们遇到一个问题,xdata在Undo上显示为null。我们使用Xdata来跟踪自定义对象/块。在我们转移到AutoCAD2016后,我们已经开始注意到这一点。

我已经包含了一个例子。运行命令 DrawRectangleWithXdata 将创建带有一些xdata的折线。您可以在创建对象后运行命令 ShowBlockXdata 来检查这一点。

现在运行Ctrl + Z以撤消DrawRectangleWithXdata命令。 在Database_ObjectErased事件中,您可以看到Xdata为null。 无论如何我能得到这个吗?

以下代码:

public partial class MainClass : Autodesk.AutoCAD.Runtime.IExtensionApplication
{

    /// <summary>
    /// Document collection object
    /// </summary>
    DocumentCollection docCollection = null;
    public void Initialize()
    {
        docCollection = Autodesk.AutoCAD.ApplicationServices.Application.DocumentManager;
        docCollection.DocumentCreated += new DocumentCollectionEventHandler(docCollection_DocumentCreated);
    }

    public void Terminate()
    {

    }




    /// <summary>
    /// Executed whenever a new document is created/opened
    /// </summary>
    /// <param name="sender"></param>
    /// <param name="e"></param>
    void docCollection_DocumentCreated(object sender, DocumentCollectionEventArgs e)
    {
        try
        {
            e.Document.Database.ObjectModified += new ObjectEventHandler(Database_ObjectModified);
            e.Document.Database.ObjectErased += new ObjectErasedEventHandler(Database_ObjectErased);
            e.Document.Database.ObjectAppended += new ObjectEventHandler(Database_ObjectAppended);
        }
        catch { }             
    }

    private void Database_ObjectModified(object sender, ObjectEventArgs e)
    {
        object xdata = e.DBObject.XData;
    }

    private void Database_ObjectErased(object sender, ObjectErasedEventArgs e)
    {
        object xdata = e.DBObject.XData;
    }

    private void Database_ObjectAppended(object sender, ObjectEventArgs e)
    {
        object xdata = e.DBObject.XData;
    }


    /// <summary>
    /// This method registers the Application name for XData
    /// </summary>
    /// <param name="regAppName">Application name to be registered</param>
    public void AddRegAppTableRecord(string regAppName)
    {
        Document doc = Autodesk.AutoCAD.ApplicationServices.Application.DocumentManager.MdiActiveDocument;
        Editor ed = doc.Editor;
        Database db = doc.Database;

        using (Transaction tr = HostApplicationServices.WorkingDatabase.TransactionManager.StartTransaction())
        {
            RegAppTable regAppTable = (RegAppTable)tr.GetObject(db.RegAppTableId, OpenMode.ForRead, false);
            if (!regAppTable.Has(regAppName))
            {
                regAppTable.UpgradeOpen();
                RegAppTableRecord ratr = new RegAppTableRecord();
                ratr.Name = regAppName;
                regAppTable.Add(ratr);
                tr.AddNewlyCreatedDBObject(ratr, true);
            }
            tr.Commit();
        }
    }


    [CommandMethod("ShowBlockXdata", CommandFlags.UsePickSet)]
    public void ShowBlockXdata()
    {
        Editor ed = Application.DocumentManager.MdiActiveDocument.Editor;
        var ss = ed.SelectImplied();
        if (ss.Status == PromptStatus.OK)
        {
            using (Transaction tx = HostApplicationServices.WorkingDatabase.TransactionManager.StartTransaction())
            {
                foreach (ObjectId objId in ss.Value.GetObjectIds())
                {
                    DBObject dbObject = tx.GetObject(objId, OpenMode.ForRead);
                    ed.WriteMessage(dbObject.XData.ToString());
                }
            }
        }
    }



    [CommandMethod("DrawRectangleWithXdata")]
    public void DrawRectangle()
    {
        //Polyline rectangle
        var p = new Autodesk.AutoCAD.DatabaseServices.Polyline(4);
        p.AddVertexAt(0, new Point2d(0, 0), 0, 0, 0);
        p.AddVertexAt(0, new Point2d(10, 0), 0, 0, 0);
        p.AddVertexAt(0, new Point2d(0, 10), 0, 0, 0);
        p.AddVertexAt(0, new Point2d(10, 10), 0, 0, 0);

        Database db = HostApplicationServices.WorkingDatabase;
        Document doc = Autodesk.AutoCAD.ApplicationServices.Application.DocumentManager.MdiActiveDocument;
        Editor ed = doc.Editor;

        Transaction tr = db.TransactionManager.StartTransaction();

        using (tr)
        {
            BlockTableRecord btr = (BlockTableRecord)tr.GetObject(db.CurrentSpaceId, OpenMode.ForWrite);
            btr.AppendEntity(p);
            tr.AddNewlyCreatedDBObject(p, true);

            AddRegAppTableRecord("MY_OBJECT");

            List<TypedValue> xdata = new List<TypedValue>();
            xdata.Add(new TypedValue(1001, "MY_OBJECT"));
            xdata.Add(new TypedValue(1070, 1234));

            ResultBuffer resBuffer = new ResultBuffer(xdata.ToArray());

            p.XData = resBuffer;

            tr.Commit();
        }
    }


}

2 个答案:

答案 0 :(得分:0)

我相信对于UNDO / REDO,您需要跟踪Unappended和Reappended事件。

答案 1 :(得分:0)

尝试放置此块:

btr.AppendEntity(p);
tr.AddNewlyCreatedDBObject(p, true);

行后:

p.XData = resBuffer;

像这样:

BlockTableRecord btr = (BlockTableRecord)tr.GetObject(db.CurrentSpaceId, OpenMode.ForWrite);

AddRegAppTableRecord("MY_OBJECT");

List<TypedValue> xdata = new List<TypedValue>();
xdata.Add(new TypedValue(1001, "MY_OBJECT"));
xdata.Add(new TypedValue(1070, 1234));

ResultBuffer resBuffer = new ResultBuffer(xdata.ToArray());

p.XData = resBuffer;

btr.AppendEntity(p);
tr.AddNewlyCreatedDBObject(p, true);

tr.Commit();
相关问题