通过从 WPF DataGrid 获取的 ID 选择 Revit 元素

Selecting a Revit Element by the ID taken from WPF DataGrid

在直接跳到问题之前,我将简要描述一下我要编写的代码。基本上,我正在尝试做一个 Revit 加载项,它打开一个 WPF 对话框,显示活动视图中元素的 idcategoryName,当双击包含 [= 的单元格时12=],对话框关闭,带有 id 的元素被 selected.

双击后出现问题。因为 Execute() 命令在对话框显示后结束,所以我无法再执行 Selection.

Command.cs

[Transaction(TransactionMode.Manual)]
   public class Command : IExternalCommand
   {
      static List<Element> elemList = new List<Element>();

      public Result Execute(
        ExternalCommandData commandData,
        ref string message,
        ElementSet elements)
      {
         UIApplication uiapp = commandData.Application;
         UIDocument uidoc = uiapp.ActiveUIDocument;
         Application app = uiapp.Application;
         Document doc = uidoc.Document;

         //List<Element> elemList = new List<Element>();

         FilteredElementCollector allElementsInView = new FilteredElementCollector(doc, doc.ActiveView.Id);
         IList elementsInView = (IList)allElementsInView.ToElements();

         foreach (Element elem in elementsInView)
         {
            elemList.Add(elem);
         }

         OpenDialog();

         return Result.Succeeded;
      }
      
      public static void SelectElementById(ElementId id)
      {

      }

      public static List<Element> SendElements()
      {
         return elemList;
      }

      public void OpenDialog()
      {
         ElementListDialog dialog = new ElementListDialog();

         dialog.Show();
      }

   }
}

正如您在上面看到的,我还有一个从 ElementListDialog.xaml.cs class 调用的 SelectElementById(...) 方法。下面您将看到填充 DataGridMouseButtonDoubleClick 方法的功能,该方法获取单元格的值并将 ElementId 类型的 id 传回 Command.cs

ElementListDialog.xaml.cs

private List<Element> elemList;
      public ElementListDialog()
      {
         InitializeComponent();
         Lab8.Command.SendElements();
         elemList = Lab8.Command.SendElements();

         //elemList = _elemList;

         Content content = new Content();

         foreach (var elem in elemList)
         {
            content = new Content();
            content.id = elem.Id;
            content.categName = elem.Category.Name;

            var finalList = new Content
            {
               id = content.id,
               categName = content.categName
            };
            
            ElementDataGrid.Items.Add(finalList);
            
         }
      }

      private void ElementDataGrid_MouseDoubleClick(object sender, MouseButtonEventArgs e)
      {
         var grid = sender as DataGrid;

         var cellValue = grid.SelectedValue;
         Content content = new Content();

         content = (Content)cellValue;
         
         Command.SelectElementById(content.id);
      }

因此;我应该如何设计 SelectElementById 方法,以便我能够通过 id select 某个元素?还是当前代码不允许执行此操作?

当前代码没问题。您需要获取活动视图并使用事务在当前视图中设置元素

public static void SelectElementById(ElementId id)
    {
        ICollection<ElementId> to_showids = new List<ElementId>();
        to_showids.Add(id);

        //RESET ELEMENTS IN VIEW
        var itrans = new Transaction(YOURDOCUMENT, "Show Element");
        using(itrans)
        {
            itrans.Start();
            //The below step is to make sure that any previous selection is removed and only your new selection is set.
            YOURDOC_UI.Selection.SetElementIds(to_showids);
            itrans.Commit();
        }

        //SHOW ELEMENTS
        YOURDOC_UI.ShowElements(to_showids);
    }

选择元素或某些 UI 交互不需要交易。 但是,如果您想要更改数据网格中的元素 属性 并在 revit 中应用更改,那么您将需要交易。

您可以 运行 您的 WPF window 在不同的线程上,以免阻塞 Revit UI。 然后您可以使用 IExternalEventHandler 在有效的 Revit API context

中执行代码
class DoSomethingOnEventRaised : IExternalEventHandler
{
    public void Execute(UIApplication uiapp)
    {
        //code to be executed in API context
    }
}

IExternalEventHandler doSomethingEvHandler = new DoSomethingOnEventRaised();
ExternalEvent doSomethingEvent = ExternalEvent.Create(calculationSupport);

doSomethingEvent.Raise() will execute the code