3 自己的工具按钮

上次的例子只能在“附加模块”→“外部工具”下运行,用作个人作品是没问题,如果打算搞个公司产品的话,估计BOSS是不会满意的。这次我来做一个直接显示在“附加模块”选项卡上的工具按钮。

3.1 基础

1、新建一个项目WelcomeToRevit。添加引用RevitAPI.dll和RevitAPI.dll。具体做法和上次一样,不赘述。

2、保留指令
using System;
添加指令
using Autodesk.Revit.DB;
using Autodesk.Revit.UI;
using Autodesk.Revit.Attributes;

3、把默认生成的public class Class1{}改成
public class Class1: IExternalApplication{}

4、在public class Class1: IExternalApplication{}内部添加两个函数OnStartup(UIControlledApplication application){}和OnShutdown(UIControlledApplication application){},分别用Result加以约束,并设定返回值为Succeeded。

5、在OnStartup(UIControlledApplication application){}内添加以下内容:
RibbonPanel ribbonPanel = application.CreateRibbonPanel("演示");
PushButtonData buttonData = new PushButtonData("cmdWelcomeToRevit","欢迎",@"C:\RevitBlog\Projects\WelcomeToRevit\WelcomeToRevit\bin\Debug\WelcomeToRevit.dll","WelcomeToRevit.Class2");
PushButton pushButton = ribbonPanel.AddItem(buttonData) as PushButton;
pushButton.ToolTip = "欢迎来到Revit。";

6、在命名空间WelcomeToRevit内部(不是Class1内部)添加一个类Class2,继承于IExternalCommand接口类。在该类前面添加[Transaction(TransactionMode.ReadOnly)],在入口函数里添加内容TaskDialog.Show("RevitDemo", "Welcome To Revit!");并返回Succeeded。

7、完成后的代码如下:

  1. 1 using System;
  2. 2 using Autodesk.Revit.DB;
  3. 3 using Autodesk.Revit.UI;
  4. 4 using Autodesk.Revit.Attributes;
  5. 5
  6. 6 namespace WelcomeToRevit
  7. 7 {
  8. 8 public class Class1: IExternalApplication
  9. 9 {
  10. 10 public Result OnStartup(UIControlledApplication application)
  11. 11 {
  12. 12 RibbonPanel ribbonPanel = application.CreateRibbonPanel("演示");
  13. 13
  14. 14 PushButtonData buttonData = new PushButtonData("cmdWelcomeToRevit","欢迎",@"C:\Test\WelcomeToRevit\WelcomeToRevit\bin\Debug\WelcomeToRevit.dll","WelcomeToRevit.Class2");
  15. 15 PushButton pushButton = ribbonPanel.AddItem(buttonData) as PushButton;
  16. 16
  17. 17 pushButton.ToolTip = "欢迎来到Revit。";
  18. 18
  19. 19 return Result.Succeeded;
  20. 20 }
  21. 21 public Result OnShutdown(UIControlledApplication application)
  22. 22 {
  23. 23 return Result.Succeeded;
  24. 24 }
  25. 25 }
  26. 26
  27. 27 [Transaction(TransactionMode.ReadOnly)]
  28. 28 public class Class2 : IExternalCommand
  29. 29 {
  30. 30 public Result Execute(ExternalCommandData commandData, ref string message, ElementSet elements)
  31. 31 {
  32. 32 TaskDialog.Show("RevitDemo", "Welcome To Revit!");
  33. 33 return Result.Succeeded;
  34. 34 }
  35. 35 }
  36. 36 }

仔细对比一下上个例子,会发现只是多了从8行到25行这一段。
8行,声明一个类,继承自RevitAPI的IExternalApplication(外部程序)接口。与IExternalCommand不同,IExternalApplication用两个成员函数OnStartup和OnShutdown来对应启动和关闭状态。
10行,重载OnStartup函数。
12行,实例化对象RibbonPanel,并通过CreateRibbonPanel方法新建一个面板,这个面板是用来承载按钮的,面板下方显示“演示”字样。
14行,实例化对象PushButtonData,并通过构造函数新建一个按钮数据。该构造函数有四个参数:第一个是程序内部使用的按钮名称,这个只要注意不要重名就可以;第二个是用户可见的按钮文字,这个可以自己随便写;第三个是按钮对应的类库地址,即dll的路径,要按实际的填;第四个是按钮命令实现代码的类名,这里要和28行对应。其中第三个参数前面的@用来忽略后面的转义字符“\”,这是个很实用的小技巧。
15行,根据按钮数据实例化对象PushButton,并把这个按钮添加到面板上。
17行,给按钮添加一个提示,当鼠标停在上面时会出现相应提示。

8、编写WelcomeToRevit.addin复制到revit插件目录下。

  1. 1 <?xml version ="1.0" encoding ="utf-8" standalone ="no"?>
  2. 2 <RevitAddIns>
  3. 3 <AddIn Type="Application">
  4. 4 <Assembly>
  5. 5 C:\test\WelcomeToRevit\WelcomeToRevit\bin\Debug\WelcomeToRevit.dll
  6. 6 </Assembly>
  7. 7 <AddInId>86394068-436d-4d15-ba53-96eefd77252c</AddInId>
  8. 8 <Name>WelcomeToRevit</Name>
  9. 9 <FullClassName>WelcomeToRevit.Class1</FullClassName>
  10. 10 <VendorId>NAME</VendorId>
  11. 11 </AddIn>
  12. 12 </RevitAddIns>

对比上个例子,有几点不同:
<AddIn Type>标签由"Command"变成"Application",表明本插件是外部应用而不是外部命令。
没有<Text>标签,这个标签对外部应用不起作用。
增加<Name>标签,为插件指定一个名字,这个标签只用于外部应用。

3.2 美化

测试一下刚完成的插件,这次在“附加模块”里出现了独立的按钮,执行后弹出对话框,不过没有图片,看上去不够美观。接着我来个它添加图片。

1、在本插件所在目录下建立一个文件夹,丢一个图片文件进去。

2、在项目中添加引用WindowsBase、PresentationCore和System.Xaml(都是框架)。

3、添加指令using System.Windows.Media.Imaging;

4、在OnStartup函数里添加如下内容:
Uri uri = new Uri(@"C:\test\WelcomeToRevit\WelcomeToRevit\bin\Debug\images\wtr.png");
BitmapImage bitmapImage = new BitmapImage(uri);
pushButton.LargeImage = bitmapImage;
也可以直接写成
pushButton.LargeImage = new BitmapImage(new Uri(@"C:\test\WelcomeToRevit\WelcomeToRevit\bin\Debug\images\wtr.png"));

重新编译生成,执行后看到按钮有图片了。

简单解释一下:
Autodesk.Revit.UI的PushButton有个参数LargeImage用来定义按钮图片,但这个参数的类型是BitmapImage,不能直接接收Image类型,所以要通过Uri来转换。

3.3 进阶

其实上面的代码还是有缺陷的,就是把插件和按钮图片的路径在程序里写死了,这样很不灵活。所以我还要改一下。

1、添加指令using System.Reflection;

2、在定义按钮数据的语句前加上string thisAssemblyPath = Assembly.GetExecutingAssembly().Location;用以获取程序路径。

3、把定义按钮数据的语句改成PushButtonData buttonData = new PushButtonData("cmdWelcomeToRevit","欢迎",thisAssemblyPath,"WelcomeToRevit.Class2");就是替换掉第三个参数。

插件路径的问题解决了,再来看按钮图片的问题。小火车公布的源码用的是Replace方法,用图片文件名替换掉dll文件名,但它把dll文件名写死了,所以还是不够灵活,所以我用另一个方法。

4、添加指令using System.IO;

5、在定义Uri的语句前加上string imagePath = Path.GetDirectoryName(thisAssemblyPath) + @"\images\wtr.png";

6、把定义Uri的语句改成Uri uri = new Uri(imagePath, UriKind.RelativeOrAbsolute);

最终代码如下:

  1. 1 using System;
  2. 2 using System.IO;
  3. 3 using System.Reflection;
  4. 4 using System.Windows.Media.Imaging;
  5. 5 using Autodesk.Revit.DB;
  6. 6 using Autodesk.Revit.UI;
  7. 7 using Autodesk.Revit.Attributes;
  8. 8
  9. 9 namespace WelcomeToRevit
  10. 10 {
  11. 11 public class Class1: IExternalApplication
  12. 12 {
  13. 13 public Result OnStartup(UIControlledApplication application)
  14. 14 {
  15. 15 RibbonPanel ribbonPanel = application.CreateRibbonPanel("演示");
  16. 16
  17. 17 string thisAssemblyPath = Assembly.GetExecutingAssembly().Location;
  18. 18 PushButtonData buttonData = new PushButtonData("cmdWelcomeToRevit","欢迎",thisAssemblyPath,"WelcomeToRevit.Class2");
  19. 19 PushButton pushButton = ribbonPanel.AddItem(buttonData) as PushButton;
  20. 20
  21. 21 pushButton.ToolTip = "欢迎来到Revit。";
  22. 22
  23. 23 string imagePath = Path.GetDirectoryName(thisAssemblyPath) + @"\images\wtr.png";
  24. 24
  25. 25 Uri uri = new Uri(imagePath, UriKind.RelativeOrAbsolute);
  26. 26 BitmapImage bitmapImage = new BitmapImage(uri);
  27. 27 pushButton.LargeImage = bitmapImage;
  28. 28
  29. 29 return Result.Succeeded;
  30. 30 }
  31. 31 public Result OnShutdown(UIControlledApplication application)
  32. 32 {
  33. 33 return Result.Succeeded;
  34. 34 }
  35. 35 }
  36. 36
  37. 37 [Transaction(TransactionMode.ReadOnly)]
  38. 38 public class Class2 : IExternalCommand
  39. 39 {
  40. 40 public Result Execute(ExternalCommandData commandData, ref string message, ElementSet elements)
  41. 41 {
  42. 42 TaskDialog.Show("RevitDemo", "Welcome To Revit!");
  43. 43 return Result.Succeeded;
  44. 44 }
  45. 45 }
  46. 46 }

3.4 总结

本例主要有如下知识点:

1、外部应用类型插件的基本写法和相应配置文件的基本写法。

2、在“附加模块”选项卡里添加按钮。

3、给按钮添加图片。

4、使用相对路径。

踏上Revit二次开发之路 3 自己的工具按钮的更多相关文章

  1. 踏上Revit二次开发之路 1 准备工作

    1 准备工作 工欲善其事,必先利其器.在正式开始之前,我觉得有必要先盘点一下需要准备些什么. 1.1 硬件设备 PC机一台(谢绝Apple). 配置不能太低,至少要i3以上的cpu.4g以上的内存和支 ...

  2. 踏上Revit二次开发之路 0 序

    0 序 近来,由于工作上的需要,开始自学Revit二次开发. Revit由欧特克公司专为BIM构建,是建筑业体系中使用最广泛的软件之一.借助欧特克公司在我国市场占有率方面的绝对优势,甚至给不少人带来& ...

  3. 踏上Revit二次开发之路 2 从“HelloWorld”入手

    2 从"HelloWorld"入手 在欧特克的官方网页上有个叫<My First Plug-in Training>的项目,号称可以让一个完全没有编程基础的人照着做出一 ...

  4. Revit二次开发之绘制钢筋

    第一次在博客园上写东西,也不知道该写些什么,我想就写点最近项目到遇到的问题吧. 最近在做一个小项目,具体需求大概是在一个revit模型中的对应的楼板位置绘制钢筋. 由于刚接触Revit二次开发,之前也 ...

  5. Revit二次开发初体验

    最近换了下工作,由之前的互联网企业转入了BIM软件开发行列.具体原因不多说,作为一个程序员来说学习永无止境.下面来一个Hello World体验下Revit的二次开发 事前准备 VS Revit 20 ...

  6. Revit二次开发 推荐

    学习revit二次开发,建议还是先把revit熟悉一下,去建立一下模型,亲自感受一下是如何创建模型的流程,其中会遇到什么问题.这样在自己做二次开发的时候,一些问题自己就能提前想到,规避掉.我大概用了半 ...

  7. [Revit]Autodesk Revit 二次开发整理(资料、准备工作和环境搭建)

    1 前言 Revit被Autodesk收购之后,整理和开放了一大部分API,供开发者实现自己的功能和程序,总体来说API的功能比较完善,毕竟市面上已经出现了各式各样的插件. 本人也是初学者,在Revi ...

  8. Revit二次开发环境配置(Revit 2020 +Visual Studio 2019)

    Revit二次开发环境搭建(Revit 2019+Visual Studio 2017)准备内容 Revit 2019开发环境的搭建,需要安装的内容如下: Revit 2019(主要的开发环境) Vi ...

  9. Revit二次开发之创建风管

      在Revit中,风管用于连接管件,风道末端和机械设备,今天简单尝试了下使用RevitAPI创建风管,现分享下我的方法.   风管从类型上可分为三类:一般风管,软风管和风管占位符:从形状上也分为三类 ...

随机推荐

  1. 【Spring Boot】创建一个简单的Spring Boot的 Demo

    走进Spring Boot 文章目录 走进Spring Boot 环境搭建 新建Spring Boot项目 开始创建项目 配置JDK版本 和 Initializr Service URL 配置Proj ...

  2. element el-table表格的vue组件二次封装(附表格高度自适应)

    基于vue的el-table表格二次封装组件方法 前言 在公司实习使用vue+element-ui框架进行前端开发,使用表格el-table较为多,有些业务逻辑比较相似,有些地方使用的重复性高,如果多 ...

  3. 攻防世界—pwn—level2

    题目分析 题目提示 下载文件后首先使用checksec检查文件保护机制 使用ida打开,查看伪代码 搜索字符串发现/bash/sh 信息收集 偏移量 system的地址 /bin/sh的地址 编写脚本 ...

  4. window安装nvm

    先说一下背景,最近做的两个项目一个是祖传angularjs1.X版本另一个是react hooks结合tailwindcss,前者angularjs的node版本比较低,而tailwindcss的no ...

  5. Spring依赖注入的方式、类型、Bean的作用域、自动注入、在Spring配置文件中引入属性文件

    1.Spring依赖注入的方式 通过set方法完成依赖注入 通过构造方法完成依赖注入 2.依赖注入的类型 基本数据类型和字符串 使用value属性 如果是指向另一个对象的引入 使用ref属性 User ...

  6. three.js cannon.js物理引擎之Heightfield

    今天郭先生说一说cannon.js物理引擎之Heightfield高度场,学过场论的朋友都知道物理学中把某个物理量在空间的一个区域内的分布称为场,高度场就是与高度相关的场,而cannon.js物理引擎 ...

  7. Enables DNS lookups on client IP addresses 域名的分层结构

    虚拟域名访问,路由可以到达,但无输出. http://httpd.apache.org/docs/2.2/mod/core.html#hostnamelookups 移动解析 HttpDNS_域名解析 ...

  8. Jenkins部署web项目到Tomcat(shell脚本)

    一.首先配置Publish Over SSH插件 配置地址:系统管理-->系统设置-->Publish over SSH(需要安装Publish over SSH插件) 二.jenkins ...

  9. 接口鉴权之sign签名校验与JWT验证

    需求描述: 项目里的几个Webapi接口需要进行鉴权,同接口可被小程序或网页调用,小程序里没有用户登录的概念,网页里有用户登录的概念,对于调用方来源是小程序的情况下进行放权,其他情况下需要有身份验证. ...

  10. Docker中运行nginx

    Docker中运行nginx 1.Docker中运行nginx 2.配置文件 2.1 nginx.conf 2.2 default.conf 3.docker的镜像可以挂什么卷 部分内容原文地址: C ...