如何在WPF中通过Revit API调用类中的Execute方法
解决WPF按钮绑定Revit功能类的问题
核心前提:Revit API的运行限制
Revit API只能在Revit进程内部运行,不能在独立的第三方exe里直接调用。你的WPF窗体必须作为Revit插件的一部分,才能获取到Revit的上下文环境(比如ExternalCommandData),进而执行功能类。
完整实现步骤(带代码示例)
1. 创建Revit插件项目
打开Visual Studio,创建一个类库项目(.NET Framework版本要和Revit对应,比如Revit2024用.NET 6或.NET Framework 4.8),然后引用Revit安装目录下的两个API程序集:
RevitAPI.dllRevitAPIUI.dll
2. 编写你的Revit功能类(Class1)
让Class1实现Revit的IExternalCommand接口,这是Revit命令的标准形式:
using Autodesk.Revit.Attributes; using Autodesk.Revit.DB; using Autodesk.Revit.UI; [Transaction(TransactionMode.Manual)] // 标记需要事务操作 public class Class1 : IExternalCommand { public Result Execute(ExternalCommandData commandData, ref string message, ElementSet elements) { // 这里写你的具体Revit功能逻辑,示例:创建一段墙体 UIApplication uiapp = commandData.Application; UIDocument uidoc = uiapp.ActiveUIDocument; Document doc = uidoc.Document; // Revit修改操作必须放在事务里 using (Transaction trans = new Transaction(doc, "创建测试墙体")) { trans.Start(); // 创建墙体的代码 Line wallLine = Line.CreateBound(new XYZ(0, 0, 0), new XYZ(10, 0, 0)); Wall.Create(doc, wallLine, doc.GetDefaultElementTypeId(ElementTypeGroup.WallType), 0); trans.Commit(); } TaskDialog.Show("完成", "Revit功能执行成功"); return Result.Succeeded; } }
3. 创建WPF窗体并绑定按钮
在项目中添加一个WPF窗口(MainWindow):
XAML部分(MainWindow.xaml)
<Window x:Class="RevitWpfPlugin.MainWindow" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" Title="Revit功能面板" Height="160" Width="280"> <Grid> <!-- 绑定点击事件到执行方法 --> <Button Content="执行Revit功能" Width="200" Height="50" Margin="0" Click="ExecuteRevitFunction_Click"/> </Grid> </Window>
C#后台代码(MainWindow.xaml.cs)
通过构造函数传入Revit的UIApplication对象,确保能拿到正确的上下文:
using Autodesk.Revit.UI; using System.Windows; namespace RevitWpfPlugin { public partial class MainWindow : Window { private readonly UIApplication _revitApp; // 传入Revit应用对象,保证上下文有效 public MainWindow(UIApplication revitApp) { InitializeComponent(); _revitApp = revitApp; } private void ExecuteRevitFunction_Click(object sender, RoutedEventArgs e) { // 实例化功能类并执行 Class1 revitFunc = new Class1(); string errorMsg = ""; ElementSet elements = new ElementSet(); // 构造Revit命令所需的上下文参数 ExternalCommandData cmdData = new ExternalCommandData { Application = _revitApp }; // 执行功能 Result result = revitFunc.Execute(cmdData, ref errorMsg, elements); // 处理执行结果 if (result != Result.Succeeded) { TaskDialog.Show("执行错误", errorMsg); } } } }
4. 编写插件入口,启动WPF窗体
创建一个新的命令类,用来触发WPF窗体的显示:
using Autodesk.Revit.Attributes; using Autodesk.Revit.UI; [Transaction(TransactionMode.ReadOnly)] // 显示窗口不需要修改Revit数据 public class ShowPanelCommand : IExternalCommand { public Result Execute(ExternalCommandData commandData, ref string message, ElementSet elements) { UIApplication revitApp = commandData.Application; // 启动WPF窗口,传入Revit应用对象 MainWindow panelWindow = new MainWindow(revitApp); // 用ShowDialog()而不是Show(),适配Revit的单线程STA模型 panelWindow.ShowDialog(); return Result.Succeeded; } }
5. 配置Revit插件加载文件
在项目根目录添加一个.addin文件(比如RevitWpfPlugin.addin),告诉Revit加载你的插件:
<?xml version="1.0" encoding="utf-8"?> <RevitAddIns> <AddIn Type="Command"> <Assembly>RevitWpfPlugin.dll</Assembly> <!-- 你的插件dll名称 --> <FullClassName>RevitWpfPlugin.ShowPanelCommand</FullClassName> <!-- 入口命令的完整类名 --> <Text>打开功能面板</Text> <!-- Revit中显示的命令名称 --> <VendorId>YOUR_ID</VendorId> <!-- 自定义你的厂商ID,比如邮箱前缀 --> <VendorDescription>你的插件描述</VendorDescription> </AddIn> </RevitAddIns>
为什么你之前的代码不行?
你之前直接在第三方应用里实例化Class1并调用Execute,缺少了两个关键条件:
- 没有有效的
ExternalCommandData:这个对象只能从Revit插件的命令中获取,包含了Revit的应用上下文,第三方应用无法创建有效的实例。 - 不在Revit进程内:Revit API的所有操作都必须在Revit的进程空间中执行,独立应用无法访问Revit的内部对象。
内容的提问来源于stack exchange,提问作者Petya
相关产品推荐
相关产品推荐

