以编程方式将块导入AutoCAD(C#)

时间:2015-08-11 15:22:44

标签: c# autocad autocad-plugin

我正在为AutoCAD编写插件,并希望导入它将在开头使用的所有块,以确保它们在需要时可用。为此,我使用这种方法

public static void ImportBlocks(string[] filesToTryToImport, string filter = "")
{
    foreach (string blockToImport in filesToTryToImport)
    {
        if (blockToImport.Contains(filter))
        {
            Database sourceDb = new Database(false, true); //Temporary database to hold data for block we want to import
            try
            {
                sourceDb.ReadDwgFile(blockToImport, System.IO.FileShare.Read, true, ""); //Read the DWG into a side database
                ObjectIdCollection blockIds = new ObjectIdCollection(); // Create a variable to store the list of block identifiers

                Autodesk.AutoCAD.DatabaseServices.TransactionManager tm = sourceDb.TransactionManager;

                using (Transaction myT = tm.StartTransaction())
                {
                    // Open the block table
                    BlockTable bt = (BlockTable)tm.GetObject(sourceDb.BlockTableId, OpenMode.ForRead, false);

                    // Check each block in the block table
                    foreach (ObjectId btrId in bt)
                    {
                        BlockTableRecord btr = (BlockTableRecord)tm.GetObject(btrId, OpenMode.ForRead, false);
                        // Only add named & non-layout blocks to the copy list
                        if (!btr.IsAnonymous && !btr.IsLayout)
                        {
                            blockIds.Add(btrId);
                        }
                        btr.Dispose();
                    }
                }
                // Copy blocks from source to destination database
                IdMapping mapping = new IdMapping();
                sourceDb.WblockCloneObjects(blockIds, _database.BlockTableId, mapping, DuplicateRecordCloning.Replace, false);
                _editor.WriteMessage("\nCopied " + blockIds.Count.ToString() + " block definitions from " + blockToImport + " to the current drawing.");
            }
            catch (Autodesk.AutoCAD.Runtime.Exception ex)
            {
                _editor.WriteMessage("\nError during copy: " + ex.Message);
            }
            finally
            {
                sourceDb.Dispose();
            }
        }
    }
}

该方法似乎有效,因为它成功执行。但是,当我通过AutoCAD界面在图形中插入一个块时,它不会显示为一个选项,当我尝试以编程方式插入它时会抛出一个FileNotFound异常,这意味着它没有工作。这种方法有什么问题?提前谢谢!

编辑:这是一个不太复杂的测试方法

public static void ImportSingleBlock(string fileToTryToImport)
{
    using (Transaction tr = _database.TransactionManager.StartTransaction())
    {
        Database sourceDb = new Database(false, true); //Temporary database to hold data for block we want to import
        try
        {
            sourceDb.ReadDwgFile(fileToTryToImport, System.IO.FileShare.Read, true, ""); //Read the DWG into a side database
            _database.Insert(fileToTryToImport, sourceDb, false);
            _editor.WriteMessage("\nSUCCESS: " + fileToTryToImport);
        }
        catch (Autodesk.AutoCAD.Runtime.Exception ex)
        {
            _editor.WriteMessage("\nERROR: " + fileToTryToImport);
        }
        finally
        {
            sourceDb.Dispose();
        }
        tr.Commit();
    }
}

[CommandMethod("TESTSINGLEBLOCKIMPORTING")]
public void TestSingleBlockImporting()
{
    OpenFileDialog ofd = new OpenFileDialog();
    DialogResult result = ofd.ShowDialog();
    if (result == DialogResult.Cancel) //Ending method on cancel
    {
        return;
    }
    string fileToTryToImport = ofd.FileName;
    using (Transaction tr = _database.TransactionManager.StartTransaction())
    {
        EntityMethods.ImportSingleBlock(fileToTryToImport);
        tr.Commit();
    }
}

This file是我尝试导入的块。希望这会激励某人,因为我现在极度迷失。

1 个答案:

答案 0 :(得分:0)

您的代码是正确的,应该可以使用。事实上我确实尝试过并且工作正常。您可能缺少Commit()外部事务(您调用此ImportBlocs()方法)。检查:

using (Transaction trans = _database.TransactionManager.StartTransaction())
{
  ImportBlocks(... parameters here ...);
  trans.Commit(); // remember to call this commit, if omitted, Abort() is assumed
}