【问题标题】:Idling and ExternalEvent are not raised while an Element is selected选择元素时不会引发 Idling 和 ExternalEvent
【发布时间】: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 事件。

标签: c# wpf revit-api


【解决方案1】:

我遇到了同样的问题。

我能够确定如果选择了同一系列的元素,就会出现问题。此外,还有一个特定的阈值,从 10 到 20 或更高,在某个阈值上表现出来。

我可以通过在调用ExternalEvent.Raise() 之前取消选择元素UIDocument.Selection.SetElementIds(new List&lt;ElementId&gt;()) 来解决这个问题。如有必要,最后返回选择。

【讨论】:

  • 我有完全不同的用例,但我可以确认在某些时候调用 Raise 不会导致执行外部事件处理程序,不管它是否为零意义,在调用 raise 之前清除选择之后似乎问题消失了
猜你喜欢
  • 2017-03-19
  • 2012-04-08
  • 2018-03-31
  • 2022-11-10
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-09-06
  • 1970-01-01
相关资源
最近更新 更多