cad.net 以激活形式在前台打开cad文档
说明
在委托的学习一文中,
提供了一个函数用于输入路径获取数据库,
本文是以激活形式打开cad文档.
代码
public class OpreateCad {
[CommandMethod(nameof(test_qiantai), CommandFlags.Session)]
public void test_qiantai() {
var dm = Acap.DocumentManager;
var doc = dm.MdiActiveDocument;
var ed = doc.Editor;
// string dwgPath = AutoGo.DwgCurrentPath();
string dwgPath = AppDomain.CurrentDomain.BaseDirectory;
var ofd = new OpenFileDialog {
AutoUpgradeEnabled = false,//OpenFileDialog会卡顿,用这个就好了
Filter = "AutoCAD 图形(*.dwg)|*.dwg",
Multiselect = true,//允许同时选择多个文件
InitialDirectory = dwgPath,
};
if (ofd.ShowDialog() != DialogResult.OK) return;
var dwgPaths = ofd.FileNames;
// 这个过滤是为了:或许你要封装进去函数内呢
var pa = dwgPaths.Where(file => !File.Exists(file));
foreach(var file in pa) {
ed.WriteMessage("文件不存在: ", file);
}
pa = dwgPaths.Where(file => File.Exists(file));
var map = OpenDwgFile(pa);
// var map = GetMap(pa);
foreach(var pair in map)
pair.Value.ActiveTask(layout => ed.WriteMessage(layout.LayoutName));
}
/// <summary>
/// 前台打开dwg
/// </summary>
/// <param name="dwgPaths"></param>
Dictionary<string, Document> OpenDwgFile(IEnumerable<string> dwgPaths) {
var map = new Dictionary<string, Document>();
var set = dwgPaths.ToHashSet();
var dm = Acap.DocumentManager;
foreach(var file in set) {
#if NET35
var doc = dm.Open(file, false);
#elif NET40
var doc = DocumentCollectionExtension.Open(dm, file, false);
#else
// 这个没有返回值啊,需要用文档事件来抓...
// dm.AppContextOpenDocument(file);
var doc = dm.Open(file, false);
#endif
map.Add(file, doc);
}
return map;
}
// 你必须要设置CommandFlags.Session在命令标记上面
// doc.IsActive在初始化时会异常,有Session标记则不会是IsActive的
Dictionary<string, Document> GetMap(IEnumerable<string> dwgPaths) {
var pathSet = dwgPaths.ToHashSet();
var map = Acap.DocumentManager.Cast<Document>()
.Where(doc =>!doc.IsDisposed && pathSet.Contains(doc.Name))
.ToDictionary(doc => doc.Name, doc => doc);
return map;
}
}
public static class DocumentHelper {
// 遍历激活
// 切换文档执行之后,后续代码不执行是因为没有Session标记
public static void ActiveTask(this Document doc, Action<Layout> action) {
if (doc.IsDisposed) throw new("文档已经释放");
if (!doc.IsActive) {
Acap.DocumentManager.MdiActiveDocument = doc;
}
var db = doc.Database;
using var docLocker = doc.LockDocument(); // 锁文档,为了切换布局
using var tr = db.TransactionManager.StartTransaction();
using var bt = (BlockTable)tr.GetObject(db.BlockTableId, OpenMode.ForRead);
foreach (ObjectId btrId in bt) {
using var btr = (BlockTableRecord)tr.GetObject(btrId, OpenMode.ForRead);
if (!btr.IsLayout) continue; // 这里应该有索引才对
using var layout = (Layout)tr.GetObject(btr.LayoutId, OpenMode.ForRead);
// 非模态这里会失败,所以要锁文档
if (LayoutManager.Current.CurrentLayout != layout.LayoutName) {
LayoutManager.Current.CurrentLayout = layout.LayoutName;
}
action(layout);
}
}
}
不能doc.Dispose()否则导致切换文档内存报错,
并且没有CommandFlags.Session的话,
释放后 doc.IsActive == false.
throw new FileNotFoundException("文件不存在", dwgPath);
ed.WriteMessage("\n****此文件打开错误: " + dwgPath + "\n错误信息:" + e.Message);
访问中的文件如何判断,官方devblog推荐是追加方式访问文件
(完)
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· winform 绘制太阳,地球,月球 运作规律
· AI与.NET技术实操系列(五):向量存储与相似性搜索在 .NET 中的实现
· 超详细:普通电脑也行Windows部署deepseek R1训练数据并当服务器共享给他人
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理
· 上周热点回顾(3.3-3.9)
2019-06-24 c++篇 cad.arx 自定义实体之编译第一个项目(甜头)