CAD二次开发 添加按钮Ribbon
这篇文章是教大家怎样子创建自己的Ribbon按钮界面(如下图),以下示例代码在CAD2020中运行实现。
背景
-
创建一个属于自己的Ribbon按钮(如下图)

-
理解Ribbon、Panel、Tab的关系(如下图),一个Tab包含多个Panel,一个Panel包含多个RibbonButton

代码
using Autodesk.AutoCAD.Runtime;
using Autodesk.Windows;
using System;
using System.Collections.Generic;
using System.Drawing;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Interop;
using System.Windows.Media.Imaging;[assembly:CommandClass(typeof(CADBlogDemo.Ribbon))]
namespace CADBlogDemo
{public class Ribbon{[CommandMethod("RibbonCmd")]public void RibbonCmd(){//得到所有的Ribbon选项卡列表集合RibbonControl ribbonCtrl = ComponentManager.Ribbon;if (ribbonCtrl == null) return;//加个判断,如果有了这个选项卡就不重复添加if (ribbonCtrl.Tabs.FirstOrDefault(x => x.Title == "MyRibbon") != null) return;//添加选项卡RibbonTab tab = AddTab(ribbonCtrl, "MyRibbon", "RibbonId1", true);//添加面板RibbonPanelSource panel = AddPanel(tab, "我就是我");//添加按钮RibbonButton button = CreateRibbonButton(panel, "点我\n点我", "Demo\n", $@"{Path.GetDirectoryName(typeof(Ribbon).Assembly.Location)}\Images\123.png");}/// <summary>/// 添加Ribbon选项卡/// </summary>/// <param name="ribbonCtrl">Ribbon控制器</param>/// <param name="title">选项卡标题</param>/// <param name="id">选项卡ID</param>/// <param name="isActive">是否置为当前</param>/// <returns>RibbonTab</returns>public RibbonTab AddTab( RibbonControl ribbonCtrl, string title, string id, bool isActive){RibbonTab tab = new RibbonTab();tab.Title = title;tab.Id = id;ribbonCtrl.Tabs.Add(tab);tab.IsActive = isActive;return tab;}/// <summary>/// 添加面板/// </summary>/// <param name="tab">Ribbon选项卡</param>/// <param name="title">面板标题</param>/// <returns>RibbonPanelSource</returns>public RibbonPanelSource AddPanel(RibbonTab tab, string title){RibbonPanelSource panelSource = new RibbonPanelSource();panelSource.Title = title;RibbonPanel ribbonPanel = new RibbonPanel();ribbonPanel.Source = panelSource;tab.Panels.Add(ribbonPanel);return panelSource;}/// <summary>/// 创建按钮/// </summary>/// <param name="panel">面板</param>/// <param name="name">按钮显示名字</param>/// <param name="cmd">需要绑定的命令</param>/// <param name="photoPath">图片路径</param>/// <returns></returns>public RibbonButton CreateRibbonButton(RibbonPanelSource panel, string name, string cmd, string photoPath){RibbonButton button = new RibbonButton();button.Text = name;button.ShowText = true;Bitmap bitmap = new Bitmap(photoPath);BitmapSource bitmapSource = Imaging.CreateBitmapSourceFromHBitmap(bitmap.GetHbitmap(), IntPtr.Zero, System.Windows.Int32Rect.Empty, BitmapSizeOptions.FromEmptyOptions());button.Image = bitmapSource; //按钮图片button.LargeImage = bitmapSource; //按钮大图片button.Size = RibbonItemSize.Large;button.Orientation = System.Windows.Controls.Orientation.Vertical;button.CommandHandler = new RibbonCommandHandler();button.CommandParameter = cmd;panel.Items.Add(button);return button;}}public class RibbonCommandHandler : System.Windows.Input.ICommand{public bool CanExecute(object parameter){return true;}public event EventHandler CanExecuteChanged;public void Execute(object parameter){//is from Ribbon ButtonRibbonButton ribBtn = parameter as RibbonButton;if (ribBtn != null){//execute the command Autodesk.AutoCAD.ApplicationServices.Application.DocumentManager.MdiActiveDocument.SendStringToExecute((string)ribBtn.CommandParameter, true, false, true);}}}
}
讲解
- 先得到所有的Tab列表集合,判断是否已经存在自己的选项卡了
//得到所有的Ribbon选项卡列表集合RibbonControl ribbonCtrl = ComponentManager.Ribbon;if (ribbonCtrl == null) return;
- 新建选项卡(Tab)
/// <summary>/// 添加Ribbon选项卡/// </summary>/// <param name="ribbonCtrl">Ribbon控制器</param>/// <param name="title">选项卡标题</param>/// <param name="id">选项卡ID</param>/// <param name="isActive">是否置为当前</param>/// <returns>RibbonTab</returns>public RibbonTab AddTab( RibbonControl ribbonCtrl, string title, string id, bool isActive){RibbonTab tab = new RibbonTab();tab.Title = title;tab.Id = id;ribbonCtrl.Tabs.Add(tab);tab.IsActive = isActive;return tab;}
- 新建面板(panel)
/// <summary>/// 添加面板/// </summary>/// <param name="tab">Ribbon选项卡</param>/// <param name="title">面板标题</param>/// <returns>RibbonPanelSource</returns>public RibbonPanelSource AddPanel(RibbonTab tab, string title){RibbonPanelSource panelSource = new RibbonPanelSource();panelSource.Title = title;RibbonPanel ribbonPanel = new RibbonPanel();ribbonPanel.Source = panelSource;tab.Panels.Add(ribbonPanel);return panelSource;}
- 新建按钮(Ribbon)
/// <summary>/// 创建按钮/// </summary>/// <param name="panel">面板</param>/// <param name="name">按钮显示名字</param>/// <param name="cmd">需要绑定的命令</param>/// <param name="photoPath">图片路径</param>/// <returns></returns>public RibbonButton CreateRibbonButton(RibbonPanelSource panel, string name, string cmd, string photoPath){RibbonButton button = new RibbonButton();button.Text = name;button.ShowText = true;Bitmap bitmap = new Bitmap(photoPath);BitmapSource bitmapSource = Imaging.CreateBitmapSourceFromHBitmap(bitmap.GetHbitmap(), IntPtr.Zero, System.Windows.Int32Rect.Empty, BitmapSizeOptions.FromEmptyOptions());button.Image = bitmapSource; //按钮图片button.LargeImage = bitmapSource; //按钮大图片button.Size = RibbonItemSize.Large;button.Orientation = System.Windows.Controls.Orientation.Vertical;button.CommandHandler = new RibbonCommandHandler();button.CommandParameter = cmd;panel.Items.Add(button);return button;}
- RibbonCommandHandler类
继承于ICommand类,作用是控制按钮是否可用
public class RibbonCommandHandler : System.Windows.Input.ICommand{public bool CanExecute(object parameter){return true;}public event EventHandler CanExecuteChanged;public void Execute(object parameter){//is from Ribbon ButtonRibbonButton ribBtn = parameter as RibbonButton;if (ribBtn != null){//execute the command Autodesk.AutoCAD.ApplicationServices.Application.DocumentManager.MdiActiveDocument.SendStringToExecute((string)ribBtn.CommandParameter, true, false, true);}}}
- 最后在CAD中用Netload添加编译的Dll,运行“RibbonCmd”命令,就可以看到选项卡了

最后
创建按钮的时候,传入的是相对地址,复制代码使用的时候,可以先换成绝对地址,实现效果后再换相对地址。赶紧去实现第一个按钮吧
相关文章:
CAD二次开发 添加按钮Ribbon
这篇文章是教大家怎样子创建自己的Ribbon按钮界面(如下图),以下示例代码在CAD2020中运行实现。 背景 创建一个属于自己的Ribbon按钮(如下图) 理解Ribbon、Panel、Tab的关系(如下图)ÿ…...
[RK3568 Android12] 添加自定义启动脚本
1:定义添加的脚本 比如为displayn2k.sh #!/system/bin/sh log "displayn2k.sh begin running" sleep 5 log "displayn2k.sh sleep 8" sleep 5 log "================sleep finished==========================" #remount /system/bin/mount -o …...
API 体系构建
前言 API 是模块或者子系统之间交互的接口定义。好的系统架构离不开好的 API 设计,而一个设计不够完善的 API 则注定会导致系统的后续发展和维护非常困难。在关键环节制定明确的 API 规范有助于 Service 对内提高产品间互通的效率,对外提供一致的使用体…...
RMPE: Regional Multi-Person Pose Estimation (AlphaPose)阅读笔记
区域多人姿态估计 ICCV 2017 论文链接 代码链接 摘要: 野外多人姿态估计具有挑战性。sota人体检测器不可避免存在定位和识别误差,这些误差可能导致依赖人体检测器的单人姿态估计器(SPPE)的失败。本文提出了一种新的区域多人姿态估…...
2月16日昆明面试经历部分考题
2月16日昆明面试部分考题 1.说说em和rem的区别?rpx呢? rem是相对于根元素(HTML)进行计算,而em是相对于当前元素或父元素的字体大小,如果当前文本的字体尺寸没有设置,则相对于浏览器的默认字体…...
ARC140D One to One
ARC140D One to One 题目大意 对于一个长度为nnn的整数序列X(x1,x2,…xn)X(x_1,x_2,\dots x_n)X(x1,x2,…xn),每个元素都在111到nnn之间,令f(X)f(X)f(X)表示以下问题的答案: 有一个nnn个顶点nnn条边的无向图(可能有重边和…...
联合身份验证与Cognito
Hello大家好,我们接下来讨论AWS联合身份验证的内容。 AWS联合身份验证 对于考试,联合身份验证部分是一块非常重要的内容。那什么是联合身份验证,它是做什么用的呢? 联合身份验证,是用来允许AWS外部用户,如…...
day18_常用API之String类丶Object类
String概述 java.lang.String 类代表字符串,String类定义的变量可以用于指向字符串对象,同时String类提供了很多操作字符串的功能,我们可以直接使用。Java 程序中的所有字符串文字(例如“abc”)都为此类的对象 特点:St…...
OSG三维渲染引擎编程学习之五十五:“第五章:OSG场景渲染” 之 “5.13 一维纹理”
目录 第五章 OSG场景渲染 5.13 一维纹理 5.13.1 一维纹理介绍 5.13.2 一维纹理示例 第五章 OSG场景渲染 OSG存在场景树和渲染树,“场景数”的构建在第三章“OSG场景组织”已详细阐明,本章开始...
RTOS随笔之FreeRTOS启动与同步方法
RTOS启动与同步机制RTOS启动任务切换场景任务同步机制队列信号量事件组任务通知任务延时RTOS启动 FreeRTOS在任务创建完成后调用函数vTaskStartScheduler()启动任务调度器。 vTaskStartScheduler()任务启动函数详解 void vTaskStartScheduler( void ) {BaseType_t xReturn;xR…...
【AI/NLP】InstructGPT数据标注问题
文章目录1 背景介绍2 标记员筛选2.1 标记员筛选标准3 数据集及其标注3.1 预训练3.2 微调3.2.1 SFT-demonstration data3.2.2 RM-comparison data3.3 数据集大小4 模型实现1 背景介绍 ChatGPT的训练过程与InstructGPT相近,大致分为三步: SFT:…...
三次握手和四次挥手
文章目录TCP三次握手为什么要三次握手三次握手可以携带数据吗?三次握手失败,服务端会如何处理?ISN代表什么,意义,何要动态随机什么是半连接队列第2次握手传回了ACK,为什么还要传回SYN?为什么要四次挥手TCP…...
Jmeter常用断言之响应断言详解
响应断言是最常用的一种断言方法,主要是对响应结果中的文本内容进行断言,比如响应结果是否包含指定的值,或者是否等于指定的值。响应断言可以适用各种返回类型的响应结果,如:Test、html、application/json、applicatio…...
【Python学习笔记】36.Python3 MySQL - mysql-connector 驱动(1)
前言 MySQL 是最流行的关系型数据库管理系统,本章节为大家介绍使用 mysql-connector 来连接使用 MySQL, mysql-connector 是 MySQL 官方提供的驱动器。 Python3 MySQL - mysql-connector 驱动 我们可以使用 pip 命令来安装 mysql-connector࿱…...
计算机SCI论文课题设计需要注意什么? - 易智编译EaseEditing
课题设计就要本着严谨性和可行性来进行。实验设计的类型要选择准确,统计学的方法要运用合理,研究对象和观察指标的选择也要符合研究目的的要求,技术路线要清晰明了。 关于课题的设计的可行性也要综合考虑,比如前期的相关工作基础…...
Quartz入门教程
本文参考文章编写 Quartz 官网 Quartz 是 OpenSymphony 开源组织在 Job Scheduling 领域又一个开源项目,是完全由 Java 开发的一个开源任务日程管理系统,“任务进度管理器”就是一个在预先确定(被纳入日程)的时间到达时ÿ…...
TypeScript 学习之 function
函数可以实现抽象层,模拟类,信息隐藏和模块。 函数有:有名字的函数、匿名函数 在 JavaScript 中的函数 // 有名字的函数 function add(x, y) {return x y; }// 匿名函数 let myAdd function (x, y) {return x y; };函数类型 typescript 可…...
【云计算自学路线】
云计算包含的技术内容和涉及的方向比较多,一定要进行系统化的学习才能更好的掌握这门技术。 云计算作为互联网新技术领域,现阶段也是出于高速发展期,想学习加入云计算行业的小伙伴可以抓紧机会了,跟着小课一起来了解云计算以及它…...
code01 v2黑屏、花屏、死机、断电重启、休眠死机的进来
症状解决 长话简说,症状如下: 使用浏览器、播放视频等,遇到突然死机或花屏死机的情况 关闭硬件加速,如:浏览器中设置关闭硬件加速,出现这种症状的软件都需要设置 开机电流音、播放与暂停时喇叭吱吱想、打…...
分享107个HTML电子商务模板,总有一款适合您
分享107个HTML电子商务模板,总有一款适合您 107个HTML电子商务模板下载链接:https://pan.baidu.com/s/1VW67Wjso1BRpH7O3IlbZwg?pwd0d4s 提取码:0d4s Python采集代码下载链接:采集代码.zip - 蓝奏云 Aplustemplates 购物模板…...
C++_核心编程_多态案例二-制作饮品
#include <iostream> #include <string> using namespace std;/*制作饮品的大致流程为:煮水 - 冲泡 - 倒入杯中 - 加入辅料 利用多态技术实现本案例,提供抽象制作饮品基类,提供子类制作咖啡和茶叶*//*基类*/ class AbstractDr…...
Golang 面试经典题:map 的 key 可以是什么类型?哪些不可以?
Golang 面试经典题:map 的 key 可以是什么类型?哪些不可以? 在 Golang 的面试中,map 类型的使用是一个常见的考点,其中对 key 类型的合法性 是一道常被提及的基础却很容易被忽视的问题。本文将带你深入理解 Golang 中…...
Zustand 状态管理库:极简而强大的解决方案
Zustand 是一个轻量级、快速和可扩展的状态管理库,特别适合 React 应用。它以简洁的 API 和高效的性能解决了 Redux 等状态管理方案中的繁琐问题。 核心优势对比 基本使用指南 1. 创建 Store // store.js import create from zustandconst useStore create((set)…...
解锁数据库简洁之道:FastAPI与SQLModel实战指南
在构建现代Web应用程序时,与数据库的交互无疑是核心环节。虽然传统的数据库操作方式(如直接编写SQL语句与psycopg2交互)赋予了我们精细的控制权,但在面对日益复杂的业务逻辑和快速迭代的需求时,这种方式的开发效率和可…...
MMaDA: Multimodal Large Diffusion Language Models
CODE : https://github.com/Gen-Verse/MMaDA Abstract 我们介绍了一种新型的多模态扩散基础模型MMaDA,它被设计用于在文本推理、多模态理解和文本到图像生成等不同领域实现卓越的性能。该方法的特点是三个关键创新:(i) MMaDA采用统一的扩散架构…...
对WWDC 2025 Keynote 内容的预测
借助我们以往对苹果公司发展路径的深入研究经验,以及大语言模型的分析能力,我们系统梳理了多年来苹果 WWDC 主题演讲的规律。在 WWDC 2025 即将揭幕之际,我们让 ChatGPT 对今年的 Keynote 内容进行了一个初步预测,聊作存档。等到明…...
第25节 Node.js 断言测试
Node.js的assert模块主要用于编写程序的单元测试时使用,通过断言可以提早发现和排查出错误。 稳定性: 5 - 锁定 这个模块可用于应用的单元测试,通过 require(assert) 可以使用这个模块。 assert.fail(actual, expected, message, operator) 使用参数…...
【Java_EE】Spring MVC
目录 Spring Web MVC 编辑注解 RestController RequestMapping RequestParam RequestParam RequestBody PathVariable RequestPart 参数传递 注意事项 编辑参数重命名 RequestParam 编辑编辑传递集合 RequestParam 传递JSON数据 编辑RequestBody …...
多模态大语言模型arxiv论文略读(108)
CROME: Cross-Modal Adapters for Efficient Multimodal LLM ➡️ 论文标题:CROME: Cross-Modal Adapters for Efficient Multimodal LLM ➡️ 论文作者:Sayna Ebrahimi, Sercan O. Arik, Tejas Nama, Tomas Pfister ➡️ 研究机构: Google Cloud AI Re…...
基于TurtleBot3在Gazebo地图实现机器人远程控制
1. TurtleBot3环境配置 # 下载TurtleBot3核心包 mkdir -p ~/catkin_ws/src cd ~/catkin_ws/src git clone -b noetic-devel https://github.com/ROBOTIS-GIT/turtlebot3.git git clone -b noetic https://github.com/ROBOTIS-GIT/turtlebot3_msgs.git git clone -b noetic-dev…...

