【发布时间】:2020-05-29 19:09:56
【问题描述】:
我正在使用 WPF 无模式对话框构建 Revit 插件,并且我想使用 ExternalEvent 来检索用户选择的元素。我正在做的事情是否可行,我需要进行哪些更改才能使其发挥作用?
由于我没有有效的 API 文档上下文,因此我会在单击按钮以检索当前选定元素的 UniqueId 时引发 ExternalEvent。
这里是相关的类(我尽量减少代码):
public class App : IExternalApplication {
internal static App _app = null;
public static App Instance => _app;
public Result OnStartup(UIControlledApplication application) {
_app = this;
return Result.Succeeded;
}
public void ShowWin(UIApplication ui_app) {
var eventHandler = new CustomEventHandler();
var externalEvent = ExternalEvent.Create(eventHandler);
var window = new WPFWindow(eventHandler, externalEvent);
Process proc = Process.GetCurrentProcess();
WindowInteropHelper helper = new WindowInteropHelper(window) {
Owner = proc.MainWindowHandle
};
window.Show();
}
}
public class AddIn : IExternalCommand {
public Result Execute(ExternalCommandData commandData, ref string message, ElementSet elements) {
App.Instance.ShowWin(commandData.Application);
return Result.Succeeded;
}
}
public class CustomEventHandler : IExternalEventHandler {
public event Action<List<string>> CustomEventHandlerDone;
public void Execute(UIApplication ui_app) {
UIDocument ui_doc = ui_app.ActiveUIDocument;
if (ui_doc == null) {
return;
}
Document doc = ui_doc.Document;
List<string> element_ids = null;
var ui_view = ui_doc.GetOpenUIViews().Where(x => x.ViewId == doc.ActiveView.Id).FirstOrDefault();
if (doc.ActiveView is View3D view3d && ui_view != null) {
using (Transaction tx = new Transaction(doc)) {
tx.Start();
element_ids = ui_doc.Selection.GetElementIds().Select(x => doc.GetElement(x)?.UniqueId).Where(x => x != null).ToList();
tx.Commit();
}
}
this.CustomEventHandlerDone?.Invoke(element_ids);
}
}
public partial class WPFWindow {
private CustomEventHandler _eventHandler;
private ExternalEvent _externalEvent;
public WPFWindow(CustomEventHandler eventHandler, ExternalEvent externalEvent) {
this._eventHandler = eventHandler;
this._eventHandler.CustomEventHandlerDone += this.WPFWindow_CustomEventDone;
this._externalEvent = externalEvent;
}
private void Button_Click(object sender, RoutedEventArgs e) {
this._externalEvent.Raise();
}
private void WPFWindow_CustomEventDone(List<string> element_ids) {
// this point is never reached while an element is selected
}
}
当一个元素被选中时,ExternalEvent 被标记为挂起,但只有在用户清除选择时才会执行。
UIControlledApplication.Idling 也是如此。
我希望即使在选择元素时也能执行它,或者以其他方式执行它,而不涉及 PickObject。
【问题讨论】:
-
你真的是说,当 Revit 中当前选定和突出显示的元素集合不为空时,永远不会触发 Idling 事件?
-
我必须在这方面纠正自己。它不是从来没有被解雇过的。但是,有些配置中的事件“始终不被触发”。似乎与选择了哪些元素有关。如果我以“rac_basic_sample_project.rvt”文件为例,当我的 WPF 窗口在屏幕上时,在选择屋顶 (ID 243274) 时不会触发 Idling 事件。