以编程方式导入块到AutoCAD (c#)

本文关键字:AutoCAD 编程 方式 导入 | 更新日期: 2023-09-27 18:07:23

我正在为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();
    }
}

这个文件是我要导入的块。

以编程方式导入块到AutoCAD (c#)

您的代码是正确的,应该可以工作。事实上,我试过了,效果很好。您可能错过了Commit()外部事务(在此调用ImportBlocs()方法)。检查:

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

我有同样的问题,非常相似的代码。问题是

_database.Insert(fileToTryToImport, sourceDb, false);

应该

_database.Insert(blockName, sourceDb, false);

可以看到,第一个参数必须是"blockName",而不是文件路径。