Revit API 创建模仿官方的实时显示的Dockablepanel

news/2025/12/6 18:52:41/文章来源:https://www.cnblogs.com/miki969696/p/19316388

Revit API 创建模仿官方的实时显示的Dockablepanel

主要是使用了idling事件和dockablepane api

 

就像revit自带的属性面板一样,选择图元时自动切换成图元的属性,这里只显示了ElementID等基本信息

 

必须用WPF窗口,不能用winforms

 

Revit开发中的可停靠面板(DockablePanel)必须在IExternalApplication中注册。以下是具体原因:

注册要求

  • 接口规定DockablePane的注册是通过UIControlledApplication接口的RegisterDockablePane方法实现的。
  • 生命周期管理IExternalApplication提供了OnStartupOnShutdown方法,分别在Revit启动和关闭时执行,适合进行可停靠面板的注册和清理。

其他方式注册的局限性

  • 外部命令(IExternalCommand
    • 无法显示面板:虽然在IExternalCommand中可以注册DockablePane,但无法使其显示。调用Show()方法会报错。
    • 生命周期不匹配IExternalCommand仅在命令执行期间有效,无法持续管理面板的生命周期。

 

话不多说直接上代码

 

using Autodesk.Revit.Attributes;
using Autodesk.Revit.DB;
using Autodesk.Revit.UI;
using Autodesk.Revit.UI.Events;
using System;
using System.Linq;
using System.Reflection;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Media;namespace RealTimeSelectionPanel
{// Ribbon 按钮:显示/隐藏面板[Transaction(TransactionMode.Manual)]public class ShowPaneCommand : IExternalCommand{public Result Execute(ExternalCommandData commandData, ref string message, ElementSet elements){DockablePane pane = commandData.Application.GetDockablePane(App.PaneId);if (pane.IsShown())pane.Hide();elsepane.Show();return Result.Succeeded;}}// 程序入口public class App : IExternalApplication{public static DockablePaneId PaneId = new DockablePaneId(new Guid("D8F6A921-3C5E-4B2A-9F1D-7E8B5C9A1F3E"));public static UIControlledApplication ControlledApp { get; private set; }public Result OnStartup(UIControlledApplication application){ControlledApp = application;// 创建 RibbonRibbonPanel rp = application.CreateRibbonPanel("实时面板");PushButtonData pbd = new PushButtonData("ShowRealTimePane","实时选中信息",Assembly.GetExecutingAssembly().Location,typeof(ShowPaneCommand).FullName);PushButton pb = rp.AddItem(pbd) as PushButton;pb.ToolTip = "打开右侧实时显示选中元素信息的面板";// 注册 DockablePane(关键:传入自己作为 provider)application.RegisterDockablePane(PaneId, "实时选中信息", new SelectionMonitorProvider());return Result.Succeeded;}public Result OnShutdown(UIControlledApplication application) => Result.Succeeded;}// 核心类:负责创建面板 + 监听 Idlingpublic class SelectionMonitorProvider : IDockablePaneProvider{private static TextBlock _infoTextBlock;public void SetupDockablePane(DockablePaneProviderData data){var root = new StackPanel{Background = new SolidColorBrush(System.Windows.Media.Color.FromRgb(250, 250, 250)),Margin = new Thickness(0)};root.Children.Add(new TextBlock{Text = "实时选中元素信息",FontSize = 18,FontWeight = FontWeights.Bold,Margin = new Thickness(0, 0, 0, 20),HorizontalAlignment = HorizontalAlignment.Center,Foreground = new SolidColorBrush(System.Windows.Media.Color.FromRgb(0, 110, 200))});_infoTextBlock = new TextBlock{Text = "请在视图中选择元素",FontSize = 15,TextWrapping = TextWrapping.Wrap,Foreground = Brushes.Gray,Background = Brushes.White,Padding = new Thickness(12),MinHeight = 120};var border = new Border{Child = _infoTextBlock,BorderBrush = Brushes.White,BorderThickness = new Thickness(1),CornerRadius = new CornerRadius(6),Background = Brushes.White};root.Children.Add(border);data.FrameworkElement = root;data.InitialState = new DockablePaneState { DockPosition = DockPosition.Right };App.ControlledApp.Idling += OnIdling;}// 每帧都会进来一次,非常快,非常安全private static void OnIdling(object sender, IdlingEventArgs e){if (_infoTextBlock == null) return;UIApplication uiApp = sender as UIApplication;if (uiApp?.ActiveUIDocument == null) return;UIDocument uidoc = uiApp.ActiveUIDocument;Document doc = uidoc.Document;var ids = uidoc.Selection.GetElementIds();string text;if (ids == null || ids.Count == 0){text = "未选中任何元素";}else if (ids.Count == 1){Element elem = doc.GetElement(ids.First());text = $"ID: {elem.Id.IntegerValue}\n" +$"类别: {elem.Category?.Name ?? "无"}\n" +$"名称: {elem.Name ?? "无"}\n" +$"类型: {doc.GetElement(elem.GetTypeId())?.Name ?? "无"}";}else{text = $"选中了 {ids.Count} 个元素\n第一个 ID: {ids.First().IntegerValue}";}// 直接更新 UI(因为 Idling 本来就在主线程)_infoTextBlock.Text = text;_infoTextBlock.Foreground = ids.Count > 0 ? new SolidColorBrush( System.Windows.Media.Color.FromRgb(0, 120, 0)) : Brushes.Gray;}}
}

 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/990453.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

企业智能体化:从系统堆叠到智能体矩阵的组织进化

文章首先界定信息化、数字化与智能化的能力边界,并在多智能体系统与“Agentic AI”最新进展基础上给出企业智能体的工作机理框架;其次,通过典型企业实践(如 H&M、Bosch、Sierra 以及制造与供应链领域的多智能体…

Kafka工作流程及文件存储机制 - 详解

pre { white-space: pre !important; word-wrap: normal !important; overflow-x: auto !important; display: block !important; font-family: "Consolas", "Monaco", "Courier New", …

【GitHub热门项目】(2025-11-09) - 详解

pre { white-space: pre !important; word-wrap: normal !important; overflow-x: auto !important; display: block !important; font-family: "Consolas", "Monaco", "Courier New", …

深入解析:Nginx优化与防盗链

深入解析:Nginx优化与防盗链2025-12-06 18:31 tlnshuju 阅读(0) 评论(0) 收藏 举报pre { white-space: pre !important; word-wrap: normal !important; overflow-x: auto !important; display: block !important…

[GESP202312 三级] 小猫分鱼

[GESP202312 三级] 小猫分鱼B3925 [GESP202312 三级] 小猫分鱼 题目描述 海滩上有一堆鱼,N 只小猫来分。第一只小猫把这堆鱼平均分为 N 份,多了 i<N 个,这只小猫把多的 i 个扔入海中,拿走了一份。第二只小猫接着…

实用指南:微软加速在亚洲扩展云基础设施,推动区域数字化跨越式发展

实用指南:微软加速在亚洲扩展云基础设施,推动区域数字化跨越式发展pre { white-space: pre !important; word-wrap: normal !important; overflow-x: auto !important; display: block !important; font-family: &qu…

markdown文档格式分析,再使用python对md文件进行结构化拆解

一、markdown文档 Markdown 文档本质上是:一个树状结构(Block 级) + 行内结构(Inline 级) Block 级元素(结构):heading_open → inline → heading_closeparagraph_open → inline → paragraph_closelist_ope…

CMake Uninstall

CMake does not provide a built-in uninstall command, but you can implement an uninstall process manually using the install_manifest.txt file generated during installation. Below are the steps to add an…

实用指南:通过约束编程优化医疗智能系统的伦理风险降低(下)

pre { white-space: pre !important; word-wrap: normal !important; overflow-x: auto !important; display: block !important; font-family: "Consolas", "Monaco", "Courier New", …

【Java 开发日记】大家来说一下 Mybatis 的缓存机制

pre { white-space: pre !important; word-wrap: normal !important; overflow-x: auto !important; display: block !important; font-family: "Consolas", "Monaco", "Courier New", …

Day12-20251206

本文介绍了Java中的运算符使用和优先级规则。主要内容包括:1) IDEA快捷键Shift+Enter换行和Shift+Ctrl+Enter自动补全;2) 自增自减运算符++/--的前置和后置区别;3) 逻辑运算符&&、||、!的用法;4) 位运算符…

悬架设计计算工具:开启悬架设计学习与实践的钥匙

悬架设计计算工具:开启悬架设计学习与实践的钥匙pre { white-space: pre !important; word-wrap: normal !important; overflow-x: auto !important; display: block !important; font-family: "Consolas",…

Solon AI 开发学习17 - generate - 使用复杂提示语

本文介绍了两种使用GeneratePrompt接口的方法:快速方法和定制提示语结构体。快速方法通过键值对直接构建请求,适用于简单场景;定制方法通过定义结构体类实现更规范的参数管理。两种方法都演示了如何调用阿里百炼API…

别再发愁!对比多款后锁定这6个型号,挑选高中学习机,不花冤枉钱

高中阶段的学习节奏快、知识点密集,不少家长希望通过学习机为孩子提供辅助,但面对市场上琳琅满目的产品,很容易陷入“选贵的就是好的”误区。事实上,适合高中学习的核心在于知识点覆盖的精准度、错题体系的实用性、…

[UVA1316 Supermarket]

UVA1316 Supermarket题目大意给一些物品,有过期时间和收益,让你安排卖出的顺序,使得最后的收益最大。对于每件物品,我们考虑贪心思路,每个物品我们尽量让其在接近过期的时候将其卖掉,这样的话,我们在排序的时候…

使用typora来写md文件时配置文件存放图片的路径

前言 当前typora写md文件,存放文件,如果是windows系统则默认存放在c盘的默认绝对路径中,这个时候如果想发送md文件给其他人,很容易造成图片的遗漏。 所以我们需要设置,让文件所处位置相对简单,然后提升发送md文件…

靠谱厂房拆迁法律机构排行榜 2026:专业解析与高性价比解决方案

在城市更新与产业升级的浪潮中,企业厂房拆迁纠纷日益频发,涉及土地补偿、停产损失、安置重建等多重复杂权益,一旦处理不当将给企业带来致命打击。北京作为法治资源集中地,汇聚了众多律师、律师事务所及在线律师咨询…

滥用ESC10:通过注册表配置不当实现权限提升的ADCS攻击分析

本文深入分析了Active Directory证书服务(ADCS)中的ESC10漏洞。该漏洞源于两项注册表键值(StrongCertificateBindingEnforcement和CertificateMappingMethods)的错误配置,攻击者可借此滥用Kerberos或Schannel映射…

[NOI2015 程序自动分析]

题目大意给定一些简单的约束关系,即相等和不等关系,让你判断是否合理。简单来说,我们对于 \(x_i = x_j\),说明 \(x_i\) 和 \(x_j\) 属于一个集合,将其合并即可,对于不等关系时,我们只需要判断其是否在一个集合里…

【基础】Unity着色器网格和计算对象介绍

Mesh网格定义与核心概念 顶点(Vertex)的本质与特性 顶点是构成3D模型的基本几何单元,每个顶点在三维空间中具有明确的坐标位置(x,y,z)。在Unity中,顶点不仅包含位置信息,还承载着模型【Unity Shader Graph 使用…