我正在使用WPF无模式对话框构建Revit加载项,并且我想使用ExternalEvent来检索用户选择的Elements。我正在做的事可行吗,我需要对其进行更改以使其起作用?
由于我没有有效的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。
我遇到了同样的问题。
如果选择了相同族的元素,我就能确定问题出在哪里。而且,有一个特定的阈值,从10到20或更大,可以体现出来。
我能够通过在调用UIDocument.Selection.SetElementIds(new List<ElementId>())
之前取消元素ExternalEvent.Raise()
的选择来解决此问题。然后,如果需要,最后返回选择。