Idling и ExternalEvent не поднимаются, пока выбран элемент - PullRequest
0 голосов
/ 01 апреля 2019

Я создаю 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.

...