[在选择元素时不引发空闲和外部事件

问题描述 投票:0回答:1

我正在使用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。

c# wpf revit-api
1个回答
0
投票

我遇到了同样的问题。

如果选择了相同族的元素,我就能确定问题出在哪里。而且,有一个特定的阈值,从10到20或更大,可以体现出来。

我能够通过在调用UIDocument.Selection.SetElementIds(new List<ElementId>())之前取消元素ExternalEvent.Raise()的选择来解决此问题。然后,如果需要,最后返回选择。

© www.soinside.com 2019 - 2024. All rights reserved.