CAD二次开发--Ribbon相关封装

 

菜单选项卡的封装

使用XML来创建选项卡使用案列写在前面,关于文件的说明如下

  1. 创建一个命令交互类 CommandBase
  2. 抽象菜单面板基类 IRibbonAbs
  3. 创建从代码初始化菜单类 RibbonInit
  4. 创建从配置文件初始化菜单类RibbonInitConfig
  5. 创建一个借口用于命令绑定 IRibbonUI
  6. 添加一个XML配置文件   RibbonSetting.xml
  7. 添加图片文件夹  Images  图片格式为PNG,可以为嵌入资源或者本地文件

示例项目结构

CAD二次开发--Ribbon相关封装

调用方式

using Autodesk.AutoCAD.Runtime;
using Lad.Ribbons;
using System;
using AcadApp = Autodesk.AutoCAD.ApplicationServices.Application;

namespace RibbonDemo
{
    /// <summary>
    /// 分类管理,所有模块
    /// </summary>
    public partial class AppManager : IRibbonUI, IExtensionApplication
    {
        [CommandMethod("Load_RibbonInit")]
        public void Initialize()
        {
            RibbonInitConfig ribbon = new(this, "RibbonDemo.RibbonSetting.xml");
            try
            {
                ribbon.Init();
            }
            catch (System.Exception e)
            {
                AcadApp.DocumentManager.MdiActiveDocument.Editor.WriteMessage(e.Message);
            }

        }

        public void Terminate()
        {
            throw new NotImplementedException();
        }
    }

    /// <summary>
    /// 命令
    /// </summary>
    public partial class AppManager
    {
        public Action<object> Commond { get; set; } = new Action<object>(e => Console.WriteLine("你好 Commond"));

        public static Action<object> CommondSt { get; set; } = new Action<object>(e => Console.WriteLine("你好 CommondSt"));

        public Action<object> CommondLambda = e => Console.WriteLine("你好 CommondLambda");

        public static Action<object> CommondlambdaSt = e => Console.WriteLine("你好 CommondlambdaSt");

        public void CommondMethod(object e)
        {
            Console.WriteLine("你好CommondMethod");
        }
        public static void CommondMethodSt(object e)
        {
            Console.WriteLine("你好CommondMethodSt");
        }
    }

}

注意:命令只能为一个参数,参数类型为object,返回值为void的方法或委托属性

显示结果如下,这里按钮图片随便找了几个,可以找一些好看的图片放进去

CAD二次开发--Ribbon相关封装CAD二次开发--Ribbon相关封装

CAD二次开发--Ribbon相关封装

 

 

 

XML文件内容

<?xml version="1.0" encoding="utf-8" ?>
<Ribbon>
    <RibbonTab Title="我的选项卡" Id="1001" IsActive="True">
        <RibbonPanel Title="按钮组A" Id="10011">
            <RibbonButton Text=" 设置 " Id="20001" Size="Large" ShowText="True" ShowImage="True" LargeImage="\Images\设置.png" CommandParameter="Line "
                         Orientation="Vertical" Command="Commond">
                <RibbonToolTip Title="直线" Content="创建直线" Command="Line"  ExpandedImage="\Images\按钮E.png"
                               ExpandedContent="使用LINE命令,可以创建一些连续的直线段,每条直线都是可以单独进行编辑的对象。"/>
            </RibbonButton>
            <RibbonButton Text=" 按钮E " Id="20002" Size="Large" ShowText="True" ShowImage="True" LargeImage="\Images\按钮E.png" CommandParameter="Line "
                          Orientation="Vertical" Command="Commond"/>
            <RibbonButton Text=" 按钮F " Id="20003" Size="Large" ShowText="True" ShowImage="True" LargeImage="\Images\按钮F.png" CommandParameter="Line "
                          Orientation="Vertical" Command="CommondSt"/>
            <RibbonButton Text=" 按钮G " Id="20004" Size="Large" ShowText="True" ShowImage="True" LargeImage="\Images\按钮G.png" CommandParameter="Line "
                          Orientation="Vertical" Command="CommondLambda"/>
            <RibbonButton Text=" 按钮H " Id="20005" Size="Large" ShowText="True" ShowImage="True" LargeImage="\Images\按钮H.png" CommandParameter="Line "
                          Orientation="Vertical" Command="CommondLambdaSt"/>
            <RibbonButton Text=" 按钮I " Id="20006" Size="Large" ShowText="True" ShowImage="True" LargeImage="\Images\按钮I.png" CommandParameter="Line "
                          Orientation="Vertical" Command="CommondMethod"/>
        </RibbonPanel>
        <RibbonPanel Title="按钮组B" Id="10012">
            <RibbonButton Text=" 图形检查 " Id="20007" Size="Large" ShowText="True" ShowImage="True" LargeImage="\Images\图形检查.png"
                          Orientation="Vertical" Command="CommondMethodSt"/>
            <RibbonButton Text=" 删除检查标记 " Id="20008" Size="Large" ShowText="True" ShowImage="True" LargeImage="\Images\删除.png"
                          Orientation="Vertical"/>
        </RibbonPanel>
        <RibbonPanel Title="按钮组C" Id="10013" IsVisible="True" IsEnabled="False">
            <RibbonButton Text=" 设置 " Id="20009" Size="Large" ShowText="True" ShowImage="True" LargeImage="\Images\设置.png"
                          Orientation="Vertical"/>
            <RibbonButton Text=" 按钮A " Id="20010" Size="Large" ShowText="True" ShowImage="True" LargeImage="\Images\按钮A.png"
                          Orientation="Vertical"/>
            <RibbonButton Text=" 按钮B " Id="20011" Size="Large" ShowText="True" ShowImage="True" LargeImage="\Images\按钮B.png"
                          Orientation="Vertical"/>
            <RibbonButton Text=" 按钮C " Id="20012" Size="Large" ShowText="True" ShowImage="True" LargeImage="\Images\按钮I.png"
                          Orientation="Vertical"/>
            <RibbonButton Text=" 按钮D " Id="20013" Size="Large" ShowText="True" ShowImage="True" LargeImage="\Images\按钮E.png"
                          Orientation="Vertical"/>
        </RibbonPanel>
    </RibbonTab>
</Ribbon>

命令基类

    /// <summary>
    /// 命令交互基础类
    /// </summary>
    internal class CommandBase : System.Windows.Input.ICommand
    {
        public event EventHandler CanExecuteChanged;
        /// <summary>
        /// 是否可执行,通用方法,传入委托
        /// </summary>
        /// <param name="parameter"></param>
        /// <returns></returns>
        public bool CanExecute(object parameter)
        {
            //方法为True返回True,其它情况都返回False
            return DoCanExecute?.Invoke(parameter) == true;
        }
        /// <summary>
        /// 执行
        /// </summary>
        /// <param name="parameter"></param>
        public void Execute(object parameter)
        {
            //如果不为空,执行委托
            DoExecute?.Invoke(parameter);
        }

        public Action<object> DoExecute { get; set; }
        public Func<object, bool> DoCanExecute { get; set; }
    }

菜单抽象类

using Autodesk.AutoCAD.ApplicationServices;
using Autodesk.Windows;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace Lad.Ribbons
{
    /// <summary>
    /// 菜单抽象类
    /// </summary>
    public abstract class IRibbonAbs
    {
        internal RibbonTab? Tab;
        internal string Title;
        internal string Id;

        protected IRibbonAbs(string title, string id) { Title = title; Id = id; }
        internal IRibbonAbs() { Tab = null; Title = string.Empty; Id = string.Empty; }

        #region 面板
        /// <summary>
        /// 将面板添加到RibbonTab
        /// </summary>
        /// <param name="panel">面板</param>
        /// <returns>添加后的RibbonPanel,如果RibbonTab中存在ID相同的RibbonPanel,则返回查找到的RibbonPanel</returns>
        internal RibbonPanel AddPanel(RibbonPanel panel)
        {
            if (Tab == null)
                throw new ArgumentNullException(nameof(Tab));

            if (string.IsNullOrWhiteSpace(panel.Source.Id))
            {
                Tab.Panels.Add(panel);
                return panel;
            }
            var temp = Tab.FindPanel(panel.Source.Id);
            if (temp == null)
                Tab.Panels.Add(panel);
            else
                panel = temp;

            return panel;
        }
        /// <summary>
        /// 根据名称查找面板功能组
        /// </summary>
        /// <param name="name"></param>
        /// <returns></returns>
        internal RibbonPanel? FindPanelFrom(string name)
        {
            if (string.IsNullOrWhiteSpace(name)) return null;
            return Tab?.Panels.Where(p => p.Source.Title == name).FirstOrDefault();
        }
        #endregion

        #region 按钮

        /// <summary>
        /// 添加提示信息
        /// </summary>
        /// <param name="ribbon">按钮条目</param>
        /// <param name="title">标题,like"直线"</param>
        /// <param name="content">提示内容,like"创建直线段"</param>
        /// <param name="command">命令快捷键,like"Line"</param>
        /// <param name="expandedContent">扩展提示内容,like"使用LINE命令,可以创建一些连续的直线段,每条直线都是可以单独进行编辑的对象。"</param>
        /// <param name="image ">扩展提示图片</param>
        public void SetRibbonItemToolTip(RibbonItem ribbon, string title, object content, string command, object? expandedContent = default,
            System.Windows.Media.ImageSource? image = default)
        {
            if (ribbon == null) return;
            //添加提示对象
            RibbonToolTip toolTip = new RibbonToolTip()
            {
                Title = title,
                Content = content,
                Command = command,
                ExpandedContent = expandedContent
            };

            if (image != null)
                toolTip.ExpandedImage = image;

            ribbon.ToolTip = toolTip;
        }
        #endregion

        /// <summary>
        /// 从菜单控制器初始化菜单
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="ribbon"></param>
        /// <param name="action"></param>
        internal void InitRibbon(Action<RibbonControl> action)
        {
            //程序空闲时触发的事件
            void LoadRibbonMenuOnIdle(object sender, EventArgs e)
            {
                var ribbonControl = Autodesk.Windows.ComponentManager.Ribbon;
                if (ribbonControl != null)
                {
                    Application.Idle -= LoadRibbonMenuOnIdle;
                    // Load Ribbon/Menu
                    action?.Invoke(ribbonControl);
                    if (Tab != null)
                        ribbonControl.ActiveTab = Tab;
                }
            }
            Application.Idle += LoadRibbonMenuOnIdle;

            //启动程序激活菜单的事件
            void ComponentManager_ItemInitialized(object sender, RibbonItemEventArgs e)
            {
                if (Autodesk.Windows.ComponentManager.Ribbon != null)
                    Autodesk.Windows.ComponentManager.ItemInitialized -= new EventHandler<RibbonItemEventArgs>(ComponentManager_ItemInitialized);
            }
            if (Autodesk.Windows.ComponentManager.Ribbon == null)
                Autodesk.Windows.ComponentManager.ItemInitialized += ComponentManager_ItemInitialized;
        }
    }
}

创建一个空接口

namespace Lad.Ribbons
{
    /// <summary>
    /// 从配置文件初始化菜单的调用对象需要继承当前接口
    /// </summary>
    public interface IRibbonUI
    {
    }
}

创建初始化菜单的类

using Autodesk.Windows;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Windows.Media.Imaging;
using System.Xml;

namespace Lad.Ribbons
{
    /// <summary>
    /// 从配置文件初始化菜单
    /// </summary>
    public class RibbonInitConfig : IRibbonAbs
    {
        private RibbonControl? control;
        private IRibbonUI ribbon;
        private Assembly? asm;
        private string configPath;
        private Type? RibbonType;
        protected Action<object> CommandBase = e => System.Windows.MessageBox.Show("未绑定命令");

        public RibbonInitConfig(IRibbonUI ribbonUI, string configPath) : base()
        {
            this.ribbon = ribbonUI;
            this.RibbonType = ribbonUI.GetType();
            this.asm = Assembly.GetAssembly(RibbonType);
            this.configPath = configPath;
        }
        #region 功能区回调
        const string RibbonRootNode = "Ribbon";
        const string RibbonTabNode = "RibbonTab";
        const string RibbonPanelNode = "RibbonPanel";
        const string RibbonItemNodeName = "RibbonButton";
        const string CommondAttribute = "Command";
        const string RibbonToolTipNode = "RibbonToolTip";

        public void Init()
        {
            this.InitRibbon(control =>
            {
                this.control = control;
                var xdoc = GetResourceXmlDoc(asm, configPath);
                foreach (var tab in InitRibbonTabs(xdoc))
                {
                    this.Tab = tab.Tab;
                    foreach (var panel in InitRibbonPanels(tab.Node))
                    {
                        var tempPanel = panel.Panel;
                        foreach (var btnItem in InitRibbonItems(panel.Node))
                        {
                            if (btnItem.Item == null) continue;
                            RibbonItem? tempBtn = null;
                            if ((tempBtn = tempPanel.Source.Items.Where(b => b.Text == btnItem.Item.Text).FirstOrDefault()) != null)
                                tempPanel.Source.Items.Remove(tempBtn);

                            btnItem.Item.ToolTip = InitRibbonToolTip(btnItem.Node);
                            tempPanel.Source.Items.Add(btnItem.Item);
                        }
                    }
                }
            });
        }
        #endregion
        #region Ribbon帮助
        /// <summary>
        /// 初始化选项卡
        /// </summary>
        /// <param name="xmlDoc"></param>
        /// <returns></returns>
        IEnumerable<(RibbonTab Tab, XmlNode Node)> InitRibbonTabs(XmlDocument? xmlDoc)
        {
            return xmlDoc?.SelectNodes($"/{RibbonRootNode}/{RibbonTabNode}")?.ForEach().Select(xmlNode =>
            {
                RibbonTab? temp = (!string.IsNullOrWhiteSpace(xmlNode.Attributes["Id"]?.Value) ? control?.FindTab(xmlNode.Attributes["Id"]?.Value) : null);
                bool isNew = temp == null;
                RibbonTab ribbonTab = temp ?? new RibbonTab();
                foreach (XmlAttribute attribute in xmlNode.Attributes)
                    SetProperty(ribbonTab, attribute);

                if (isNew) control?.Tabs.Add(ribbonTab);

                return (ribbonTab, xmlNode);
            }) ?? Enumerable.Empty<(RibbonTab Tab, XmlNode Node)>();
        }
        /// <summary>
        /// 初始化面板
        /// </summary>
        /// <param name="xmlNode"></param>
        /// <returns></returns>
        IEnumerable<(RibbonPanel Panel, XmlNode Node)> InitRibbonPanels(XmlNode xmlNode)
        {
            return xmlNode?.SelectNodes(RibbonPanelNode)?.ForEach().Select(node =>
            {
                RibbonPanel? temp = (!string.IsNullOrWhiteSpace(node.Attributes["Id"]?.Value) ? this.Tab?.FindPanel(node.Attributes["Id"]?.Value) : null);
                bool isNew = temp == null;

                RibbonPanel panel = temp ?? new();
                RibbonPanelSource panelSource = panel.Source ?? new();
                foreach (XmlAttribute panelAttribute in node.Attributes)
                    SetProperty(panelSource, panelAttribute);
                if (isNew)
                {
                    panel.Source = panelSource;
                    this.Tab?.Panels.Add(panel);
                }
                return (panel, node);
            }) ?? Enumerable.Empty<(RibbonPanel? Panel, XmlNode Node)>();
        }
        /// <summary>
        /// 初始化RibbonItem
        /// </summary>
        /// <param name="xmlNode"></param>
        /// <returns></returns>
        IEnumerable<(RibbonItem? Item, XmlNode Node)> InitRibbonItems(XmlNode xmlNode)
        {
            if (RibbonType == null) return Enumerable.Empty<(RibbonItem? Item, XmlNode Node)>();

            return xmlNode?.SelectNodes(RibbonItemNodeName)?.ForEach().Select(node =>
            {
                var type = Assembly.GetAssembly(typeof(RibbonItem)).GetType($"Autodesk.Windows.{node.Name}");
                if (type != null)
                {
                    var ribbonButton = System.Activator.CreateInstance(type);
                    //设置RibbonItem的属性
                    foreach (XmlAttribute btnAttribute in node.Attributes)
                    {
                        if (string.IsNullOrWhiteSpace(btnAttribute.Value)) continue;

                        //根据特性名判断是否为命令
                        if (CommondAttribute == btnAttribute.Name && typeof(RibbonCommandItem).IsAssignableFrom(type))
                        {
                            var proinfo = type.GetProperty(RibbonCommandItem.CommandHandlerPropertyName);

                            var commodMethod = (RibbonType.GetMethods().Where(m => m.Name == btnAttribute.Value && m.GetParameters().Length == 1
                            && m.GetParameters()[0].ParameterType == typeof(object)).FirstOrDefault());
                            Action<object>? doExecute = null;
                            if (commodMethod == null)
                            {
                                var pinfoMethod = RibbonType.GetProperties().Where(p => p.Name == btnAttribute.Value && typeof(Action<object>)
                                   .IsAssignableFrom(p.PropertyType)).FirstOrDefault()?.GetGetMethod();// 判断是否存在委托类型的属性
                                if (pinfoMethod != null)
                                    doExecute = pinfoMethod.Invoke(pinfoMethod.IsStatic ? null : ribbon, null) as Action<object>;
                            }
                            else
                                doExecute = Delegate.CreateDelegate(typeof(Action<object>), commodMethod.IsStatic ? null : ribbon, commodMethod) as Action<object>;

                            proinfo.SetValue(ribbonButton, new CommandBase() { DoCanExecute = e => true, DoExecute = doExecute ?? CommandBase }, null);
                        }
                        //根据特性名称获取对应的属性
                        if (CommondAttribute != btnAttribute.Name)
                        {
                            var propertyInfo = type.GetProperty(btnAttribute.Name);
                            if (propertyInfo == null) continue;

                            if (propertyInfo.PropertyType.Equals(typeof(System.Windows.Media.ImageSource)))
                            {
                                BitmapImage? image;
                                if ((image = GetImageResource(asm, btnAttribute.Value)) != null)
                                    propertyInfo.SetValue(ribbonButton, image, null);
                            }
                            else
                                propertyInfo.SetValue(ribbonButton, propertyInfo.PropertyType.IsEnum ? Enum.Parse(propertyInfo.PropertyType, btnAttribute.Value)
                                    : Convert.ChangeType(btnAttribute.Value, propertyInfo.PropertyType), null);
                        }

                    }
                    return (ribbonButton as RibbonItem, node);
                }
                return (default, node);
            }) ?? Enumerable.Empty<(RibbonItem? Item, XmlNode Node)>();

        }
        /// <summary>
        /// 初始化提示
        /// </summary>
        /// <param name="xmlNode"></param>
        /// <returns></returns>
        RibbonToolTip? InitRibbonToolTip(XmlNode xmlNode)
        {
            var node = xmlNode?.SelectSingleNode(RibbonToolTipNode);
            if (node == null) return null;

            RibbonToolTip toolTip = new();
            foreach (XmlAttribute attribute in node.Attributes)
            {
                var propertyInfo = typeof(RibbonToolTip).GetProperty(attribute.Name);
                if (propertyInfo == null) continue;

                if (propertyInfo.PropertyType.Equals(typeof(System.Windows.Media.ImageSource)))
                {
                    BitmapImage? image;
                    if ((image = GetImageResource(asm, attribute.Value)) != null)
                        propertyInfo.SetValue(toolTip, image, null);
                }
                else
                    propertyInfo.SetValue(toolTip, propertyInfo.PropertyType.IsEnum ? Enum.Parse(propertyInfo.PropertyType, attribute.Value)
                        : Convert.ChangeType(attribute.Value, propertyInfo.PropertyType), null);
            }

            return toolTip;

        }
        /// <summary>
        /// 根据节点属性设置对象的属性
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="info">实例对象</param>
        /// <param name="attribute"></param>
        void SetProperty<T>(T info, XmlAttribute attribute) where T : class
        {
            var propertyInfo = typeof(T).GetProperty(attribute.Name);
            propertyInfo?.SetValue(info, propertyInfo.PropertyType.IsEnum ? Enum.Parse(propertyInfo.PropertyType, attribute.Value)
                : Convert.ChangeType(attribute.Value, propertyInfo.PropertyType), null);
        }
        #endregion
        #region 帮助器
        /// <summary>
        /// 获取程序集的资源图片
        /// </summary>
        /// <param name="asm"></param>
        /// <param name="resourceName">图片路径</param>
        /// <returns></returns>
        private BitmapImage? GetImageResource(Assembly? asm, string resourceName)
        {
            if (string.IsNullOrWhiteSpace(resourceName) || asm == null) return null;

            var resourcefileName = asm.GetManifestResourceNames()
                          .Where(s => s.Contains(resourceName.Replace(@"\", ".")))
                          .FirstOrDefault();
            if (!string.IsNullOrWhiteSpace(resourcefileName))
                return RibbonExtensions.SteamToBitmapImage(asm.GetManifestResourceStream(resourcefileName));

            if (!string.IsNullOrWhiteSpace(asm.Location) && !string.IsNullOrEmpty(resourceName))
            {
                var dirPath = Directory.GetParent(asm.Location).FullName;
                if (File.Exists(dirPath + resourceName))
                    return new(new(dirPath + resourceName));

                if (dirPath.DirExists(resourceName.Substring(resourceName.LastIndexOf(@"\") + 1), out var path))
                    return new(new(path));
            }
            return null;
        }
        /// <summary>
        /// 获取调用程序集的配置文档
        /// </summary>
        /// <param name="asm"></param>
        /// <param name="resourceName"></param>
        /// <returns></returns>
        private XmlDocument? GetResourceXmlDoc(Assembly? asm, string resourceName)
        {
            if (asm != null)
            {
                var resourcefileName = asm.GetManifestResourceNames()
                      .Where(s => string.Compare(resourceName, s, StringComparison.OrdinalIgnoreCase) == 0)
                      .FirstOrDefault();

                if (!string.IsNullOrWhiteSpace(resourcefileName))
                {
                    using (StreamReader resourceReader = new StreamReader(asm.GetManifestResourceStream(resourcefileName)))
                    {
                        if (resourceReader != null)
                        {
                            XmlDocument xmlDoc = new XmlDocument();
                            xmlDoc.Load(resourceReader);
                            return xmlDoc;
                        }
                    }
                }

            }
            return null;
        }
        #endregion
    }

}

扩展函数

using Autodesk.Windows;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Windows.Media.Imaging;
using System.Xml;

namespace Lad.Ribbons
{
    public static class RibbonExtensions
    {
        /// <summary>
        /// 遍历节点
        /// </summary>
        /// <param name="nodeList"></param>
        /// <returns></returns>
        internal static IEnumerable<XmlNode> ForEach(this XmlNodeList nodeList)
        {
            foreach (XmlNode node in nodeList)
                yield return node;
        }

        internal static BitmapImage? SteamToBitmapImage(Stream stream)
        {
            return stream == null ? null : BitmapToBitmapImage(new(stream));
        }
        // Bitmap --> BitmapImage
        internal static BitmapImage? BitmapToBitmapImage(System.Drawing.Bitmap bitmap)
        {
            if (bitmap == null)
                return null;
            using (MemoryStream stream = new MemoryStream())
            {
                bitmap.Save(stream, System.Drawing.Imaging.ImageFormat.Png); // 坑点:格式选Bmp时,不带透明度

                stream.Position = 0;
                BitmapImage result = new BitmapImage();
                result.BeginInit();
                // According to MSDN, "The default OnDemand cache option retains access to the stream until the image is needed."
                // Force the bitmap to load right now so we can dispose the stream.
                result.CacheOption = BitmapCacheOption.OnLoad;
                result.StreamSource = stream;
                result.EndInit();
                result.Freeze();
                return result;
            }
        }

        /// <summary>
        /// 面板中添加功能按钮
        /// </summary>
        /// <param name="panel"></param>
        /// <param name="ribbonItems">按钮组</param>
        public static void AddRibbonItems(this RibbonPanel panel, params RibbonItem[] ribbonItems)
        {
            if (panel == null) throw new ArgumentNullException("RibbonPanel");
            foreach (var item in ribbonItems)
                if (!panel.Source.Items.Any(b => b.Text == item.Text))
                    panel.Source.Items.Add(item);
        }


    }
}
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace Lad.Ribbons
{
    internal static class FilePathExtension
    {
        /// <summary>
        /// 程序集目录下的子文件夹是否包含配置文件
        /// </summary>
        /// <param name="dirFullName">搜索的文件目录</param>
        /// <param name="searchName">搜索的文件名</param>
        /// <param name="path">文件路径</param>
        /// <returns>是否存在</returns>
        public static bool DirExists(this string dirFullName, string searchName, out string path)
        {
            foreach (var dir in System.IO.Directory.GetDirectories(dirFullName))
            {
                path = System.IO.Path.Combine(dir, searchName);
                if (System.IO.File.Exists(path))
                    return true;
                else
                {
                    if (DirExists(dir, searchName, out path))
                        return true;
                }
            }
            path = string.Empty;
            return false;
        }
    }
}

使用示例2

            RibbonInit ribbonInit = new RibbonInit("我的选项卡", "1001");
            ribbonInit.Init(tab =>
            {
                ribbonInit.CreatePanel("信息管理", "10011")
                .AddRibbonItems(new RibbonItem[] {
                    ribbonInit.CreatLargeButton("查询", e =>
                    {
                        var button = e as RibbonButton;
                        if (button.CommandParameter != null)//命令行发送命令
                        {
                            Document doc = AcadApp.DocumentManager.MdiActiveDocument;
                            doc.SendStringToExecute(button.CommandParameter.ToString(), true, false, false);
                        }
                    }, default, "Line ")
                });
            });
                  tab.SetRibbonItemToolTip(btn, "直线", "创建直线段", "Line", "使用Line命令,可以创建一些连续的直线段,每条直线都是可以单独进行编辑的对象",
                      new(Path.Combine(imgPath, "Images", "LineToolTip.png")));

显示结果

CAD二次开发--Ribbon相关封装

CAD二次开发--Ribbon相关封装

 

 

//查找面板、选项卡的方法
control.FindTab("1001")   //查找选项卡

control.FindPanel("10011",false) //查找面板---ID对应的是RibbonPanelSource的ID

control.ActiveTab.FindPanel("10011")//查找面板---ID对应的是RibbonPanelSource的ID

 

上一篇:springcloud入门(四)之feign


下一篇:05 Ribbon负载均衡