【问题标题】:Autocad C# - On Undo, the object Xdata becomes nullAutocad C# - 在撤消时,对象 Xdata 变为空
【发布时间】:2015-08-07 14:19:42
【问题描述】:

这是在 AutoCAD 2016 中

我们有一个问题,xdata 在撤消时显示为空。我们使用 Xdata 来跟踪自定义对象/块。我们在迁移到 AutoCAD2016 后开始注意到这一点。

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

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

代码如下:

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();
        }
    }


}

【问题讨论】:

    标签: c# autocad autocad-plugin


    【解决方案1】:

    试着把这个块:

    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();
    

    【讨论】:

    • 我将APPNAME注册分离成一个新的命令方法——'RegisterAppId',先运行它,然后运行'DrawRectangleWithXdata'命令。因此,撤消不应影响第一个命令方法“RegisterAppId”。但是,Xdata 仍然为空。
    • 你是对的。我已经更新了我的答案。它与事务无关,但与您附加实体的位置有关。
    • 太棒了!对此有何解释?它肯定存储在某个地方,因为当我移动它或删除它时,xData 是可用的。
    • 对于某些操作(例如孵化),方法调用的顺序会改变行为。在这里,如果在将实体附加到数据库之后设置 XData,它的处理方式似乎有所不同。它一定来自 AutoCAD 2016 中底层代码的更改。如果@Augusto Goncalves 与开发团队取得联系,他可能会告诉您更多信息。
    【解决方案2】:

    我认为对于 UNDO/REDO,您需要跟踪未附加和重新附加的事件。

    【讨论】:

    • 我为 Unappended 事件添加了一个处理程序,它在 Undo 中被捕获。但是,xData 仍然为空
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2018-07-10
    • 2015-12-07
    • 1970-01-01
    • 2010-12-21
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多