CAD二次开发 添加按钮Ribbon

news2024/11/16 23:55:35

这篇文章是教大家怎样子创建自己的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 Button
            RibbonButton 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 Button
            RibbonButton 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”命令,就可以看到选项卡了
    在这里插入图片描述

最后

创建按钮的时候,传入的是相对地址,复制代码使用的时候,可以先换成绝对地址,实现效果后再换相对地址。赶紧去实现第一个按钮吧

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

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

相关文章

输入任意多个整数, 把这些数据保存到文件data.txt中.(按ctrl + z)

#pragma once #include <iostream> #include <fstream> using namespace std; /* 输入任意多个整数, 把这些数据保存到文件data.txt中. 如果在输入的过程中, 输入错误, 则提示用户重新输入. 指导用户输入结束(按ctrl z) [每行最多保存10个整数] */ int main() { …

Kafka的日志同步

首先介绍下LEO和HW LEO&#xff1a; 即LogEndOffset&#xff0c;表示该副本下次日志记录的偏移量HW&#xff1a;即HighWatermark&#xff0c;高水位线&#xff0c;是所有ISR副本集合中的LEO最小值上图中&#xff0c;如果此时三个副本都在ISR集合中&#xff0c;那么此时他们的LE…

三次握手和四次挥手

文章目录TCP三次握手为什么要三次握手三次握手可以携带数据吗&#xff1f;三次握手失败&#xff0c;服务端会如何处理?ISN代表什么&#xff0c;意义&#xff0c;何要动态随机什么是半连接队列第2次握手传回了ACK&#xff0c;为什么还要传回SYN&#xff1f;为什么要四次挥手TCP…

DeepSort:论文翻译

文章目录摘要1、简介2、利用深度关联度量进行排序2.1、轨迹处理和状态估计2.3、匹配的级联2.4、深度外观描述符3、实验4、结论论文链接&#xff1a;https://arxiv.org/pdf/1703.07402.pdf摘要 简单在线实时跟踪(SORT)是一种实用的多目标跟踪方法&#xff0c;专注于简单、有效的…

PFU扫描仪将于2023年4月切换至理光品牌上

目前&#xff0c;株式会社PFU (以下简称“PFU”)在村上清治社长的带领下&#xff0c;正将其在全球拥有庞大市场份额的图像扫描仪从富士通品牌变更为理光品牌&#xff0c;涉及产品线包括fi系列、SP系列和ScanSnap系列。2022年9月1日完成公司股权转让后&#xff0c;PFU正式加入理…

【STM32笔记】低功耗模式下GPIO省电配置避坑实验(闲置引脚配置为模拟输入其实更耗电)

【STM32笔记】低功耗模式下GPIO省电配置避坑实验&#xff08;闲置引脚配置为模拟输入其实更耗电&#xff09; 前文&#xff1a; blog.csdn.net/weixin_53403301/article/details/128216064 【STM32笔记】HAL库低功耗模式配置&#xff08;ADC唤醒无法使用、低功耗模式无法烧录解…

ReportBuilder Enterprise Edition 22.0 Crack

Report Builder 的主要目的是为用户和开发人员提供全面的覆盖范围以及现有的替代方案。这个目标被认为是通过提供视觉、无障碍的答案来实现的&#xff0c;它是所有可用的四个区域。Report Builder 和报表设计器的屏幕截图能够表明它具有的用户界面符合人体工程学的布局。与 Rep…

WebDAV之π-Disk派盘+Piktures

Piktures支持WebDAV方式连接π-Disk派盘。推荐一款简单易用&#xff0c;功能超级强大的智能相册应用。Piktures智能相册是一款简单易用&#xff0c;功能超级强大的智能相册应用&#xff0c;它不仅可以访问本地和云照片&#xff0c;还可以照片编辑器&#xff0c;而且它同时还是一…

Mysql常用函数大全

本篇文章讲解是是MySQL的函数方法&#xff0c;涵盖所有的MySQL常见的方法。下面是本篇文章的目录结构&#xff0c;可以根据自己需求点击右方目录查找&#xff1a; 目录 &#xff08;一&#xff09;数字函数 &#xff08;二&#xff09;字符串函数 &#xff08;三&#xff0…

[ vulhub漏洞复现篇 ] Drupal<7.32 Drupalgeddon SQL注入漏洞(CVE-2014-3704)

&#x1f36c; 博主介绍 &#x1f468;‍&#x1f393; 博主介绍&#xff1a;大家好&#xff0c;我是 _PowerShell &#xff0c;很高兴认识大家~ ✨主攻领域&#xff1a;【渗透领域】【数据通信】 【通讯安全】 【web安全】【面试分析】 &#x1f389;点赞➕评论➕收藏 养成习…

Redis常用数据结构及应用场景

1.总体结构 Redis中的数据&#xff0c;总体上是键值对&#xff0c;不同数据类型指的是键值对中值的类型。 2.string类型 Redis中最基本的类型&#xff0c;它是key对应的一个单一值。二进制安全&#xff0c;不必担心由于编码等问题导致二进制数据变化。所以redis的string可以…

【JMeter】【Mac】如何在Mac上打开JMeter

平常我们在Windows电脑里打开JMeter&#xff0c;只要双击JMeter.bat即可打开&#xff0c;那我换了Mac后&#xff0c;该怎么打开JMeter呢 一、命令行打开JMeter 1、打开JMeter路径 cd /Users/work/apache-jmeter-5.2/bin 2、运行JMeter sh jmeter 3、如果涉及到一些权限无…

企业多会场视频直播(主会场、分会场直播)实例效果

阿酷TONY 2023-2-16 长沙 活动直播做多会场切换功能&#xff08;主会场、分会场、会场一、会场二、会场三自由切换&#xff09; 企业多会场视频直播&#xff08;主会场、分会场直播&#xff09;实例效果 特点&#xff1a;支持PC端&#xff0c;也支持移动端观看&#xff0c;会…

基于非对称纳什谈判的多微网电能共享运行优化策略(Matlab代码实现)

&#x1f4a5;&#x1f4a5;&#x1f49e;&#x1f49e;欢迎来到本博客❤️❤️&#x1f4a5;&#x1f4a5; &#x1f3c6;博主优势&#xff1a;&#x1f31e;&#x1f31e;&#x1f31e;博客内容尽量做到思维缜密&#xff0c;逻辑清晰&#xff0c;为了方便读者。 ⛳️座右铭&a…

ESP32-C2开发板

C2是一个芯片采用4毫米x 4毫米封装&#xff0c;与272 kB内存。它运行框架&#xff0c;例如ESP-Jumpstart和ESP造雨者&#xff0c;同时它也运行ESP-IDF。ESP-IDF是Espressif面向嵌入式物联网设备的开源实时操作系统&#xff0c;受到了全球用户的信赖。它由支持Espressif以及所有…

react-redux

Redux 是js容器&#xff0c;用于进行全局的 状态管理它可以用在react, angular, vue等项目中, 但基本与react配合使用三大核心&#xff1a; 单一数据源 整个应用的state被存储在一棵 object tree中&#xff0c;并且这个 object tree只存在于一个唯一的 store 中 State是只读的…

教你如何搭建人事OA-员工管理系统,demo可分享

1、简介1.1、案例简介本文将介绍&#xff0c;如何搭建人事OA-员工管理。1.2、应用场景人事OA-员工管理应用对员工信息进行管理&#xff0c;可办理入职、转正、离职等流程。2、设置方法2.1、表单搭建1&#xff09;新建表单【员工管理】&#xff0c;字段设置如下&#xff1a;名称…

004:NumPy的应⽤-2

数组的运算 使⽤NumPy 最为⽅便的是当需要对数组元素进⾏运算时&#xff0c;不⽤编写循环代码遍历每个元素&#xff0c;所有的运算都会⾃动的⽮量化&#xff08;使⽤⾼效的、提前编译的底层代码来对数据序列进⾏数学操作&#xff09;。简单的说就是&#xff0c;NumPy 中的数学运…

【数据挖掘实战】——航空公司客户价值分析(K-Means聚类案例)

目录 一、背景和挖掘目标 1、RFM模型缺点分析 2、原始数据情况 3、挖掘目标 二、分析方法与过程 1、初步分析&#xff1a;提出适用航空公司的LRFMC模型 2、总体流程 第一步&#xff1a;数据抽取 第二步&#xff1a;探索性分析 第三步&#xff1a;数据预处理 第四步&…

编码踩坑——运行时报错java.lang.NoSuchMethodError / 同名类加载问题 / 双亲委派【建议收藏】

本篇介绍一个实际遇到的排查异常的case&#xff0c;涉及的知识点包括&#xff1a;类加载机制、jar包中的类加载顺序、JVM双亲委派模型、破坏双亲委派模型及自定义类加载器的代码示例&#xff1b;问题背景业务版本&#xff0c;旧功能升级&#xff0c;原先引用的一个二方包中的du…