Я создаю Revit AddIn с немодальными диалоговыми окнами WPF и хочу использовать ExternalEvent для извлечения элементов, выбранных пользователем.Является ли то, что я делаю, жизнеспособным, и что мне нужно изменить, чтобы оно работало?
Поскольку у меня нет действительного контекста документа API, я вызываю ExternalEvent при нажатии кнопки для получения UniqueId элементовкоторые выбраны в настоящее время.
Вот соответствующие классы (я пытался уменьшить код настолько, насколько мог):
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.