AutoCAD C# RIBBOIN自动加载的研究

南胜NanSheng / 2024-10-13 / 原文

创建自定义类


 public struct AutoCADDllCommand
 {

     public string AssemblyName;

     public string clsName;

     public string MethodName;

     public string Macro;

     public MethodInfo MethodInfo;

 }


 public class MyRibbonTab
 {
     public string Title { get; set; }
     public string ID { get; set; }
     public List<AutoCADDllCommand> Commands { get; set; }

     public bool HasRibbonTab() => RibbonTabs == null ? false : RibbonTabs.Any(c => c.Title == Title && c.Id == ID);
     public static RibbonTabCollection RibbonTabs => ComponentManager.Ribbon?.Tabs;
     public MyRibbonTab(List<AutoCADDllCommand> cmdinfos, string title, string id)
     {
         Title = title;
         ID = id;
         Commands = cmdinfos;
         AddRibbonTab();
         acApp.Core.Application.SystemVariableChanged += (s, e) =>
         {
             if (e.Name.ToUpper() == "WSCURRENT")
             {
                 if (!HasRibbonTab()) AddRibbonTab();
             }
         };

         if (!HasRibbonTab())
         {
             ComponentManager.ItemInitialized -= ComponentManager_ItemInitialized;
             ComponentManager.ItemInitialized += ComponentManager_ItemInitialized;
         }
     }

     private void ComponentManager_ItemInitialized(object sender, RibbonItemEventArgs e)
     {
         if (HasRibbonTab())
         {
             ComponentManager.ItemInitialized -= ComponentManager_ItemInitialized;
             return;
         }
         AddRibbonTab();
     }

     public void AddRibbonTab()
     {
         if (RibbonTabs == null) return;
         RemoveRibbonTab();
         var ribbonTab = new RibbonTab() { Title = Title, Id = ID };
         ribbonTab.IsPanelEnabled = true;
         ribbonTab.Theme = Autodesk.Internal.Windows.TabThemes.Blue;
         var dicts = Commands.GroupBy(x => x.clsName).ToDictionary(c => c.Key, c => c.ToList().OrderBy(m => m.MethodName).ToList());
         foreach (var item in dicts)
         {
             var ribbonPanel = new RibbonPanel() {
                 FloatingOrientation = System.Windows.Controls.Orientation.Vertical,
                 CustomPanelTitleBarBackground = System.Windows.Media.Brushes.BlanchedAlmond
             };
             var rpr = new Autodesk.Windows.RibbonPanelSource() { Title = item.Key, Id = item.Key };
             var rfp = new Autodesk.Windows.RibbonFoldPanel()
             {
                 IsTopJustified = true,
                 ResizeStyle = RibbonItemResizeStyles.ChangeSize| RibbonItemResizeStyles.Collapse,
                 SubPanelResizeStyle = Autodesk.Windows.RibbonFoldPanelResizeStyle.NoResize,
                 DefaultSize = RibbonFoldPanelSize.Medium };
             foreach (var cmd in item.Value)
             {
                 var att = (CommandMethodAttribute)(cmd.MethodInfo.GetCustomAttribute(typeof(CommandMethodAttribute)));
                 var button = new Autodesk.Windows.RibbonButton
                 {
                     Name = att.GlobalName,
                     HelpTopic = "",
                     Orientation = System.Windows.Controls.Orientation.Vertical,
                     ResizeStyle = RibbonItemResizeStyles.ChangeSize,
                     Text = cmd.MethodName,
                     ShowText = true,
                     ShowImage = false,
                     IsVisible = true,
                     CommandHandler = new MyRibbonCommand(),
                     CommandParameter = cmd.Macro,
                     IsEnabled = true,
                     Size = RibbonItemSize.Standard,
                 };
                 //rrp.Items.Add(button);
                 //
                 rfp.Items.Add(button);
             }
             rpr.Items.Add(rfp);
             ribbonPanel.Source = rpr;
             //ribbonPanel.CustomPanelBackground= System.Windows.Media.Brushes.Red;
             ribbonTab.Panels.Add(ribbonPanel);
         }
         //ribbonTab.IsActive = true;
         RibbonTabs.Add(ribbonTab);
     }

     public void RemoveRibbonTab()
     {
         if (HasRibbonTab())
         {
             var ribbonTab = RibbonTabs.FirstOrDefault(c => c.Title == Title && c.Id == ID);
             if (ribbonTab != null)
             {
                 RibbonTabs.Remove(ribbonTab);
             }
         }
     }
     
      public static List<AutoCADDllCommand> GetAssemblyAutoCADCmds( Assembly ass = null)
 {
     var rtn = new List<AutoCADDllCommand>();
     if (ass == null)
         ass = Assembly.GetExecutingAssembly();
     //'提取全部的类型
     var clsColls = ass.GetTypes().Where(a => a.IsClass && a.IsPublic);
     var mis = new List<MethodInfo>();
     clsColls.ForEach(cls =>
                         {
                             var methods = cls.GetMethods().Where
                             (mi => mi.IsPublic &&
                             mi.GetCustomAttribute(typeof(CommandMethodAttribute)) != null);
                             if (methods.Any()) mis.AddRange(methods);
                         }
                     );

     if (!mis.Any()) return null;
     foreach (var mi in mis)
     {
         var att = mi.GetCustomAttribute(typeof(CommandMethodAttribute), true) as CommandMethodAttribute;
         rtn.Add(new AutoCADDllCommand()
         {
             AssemblyName = Path.GetFileNameWithoutExtension(ass.Location),
             clsName = mi.DeclaringType.Name,
             MethodName = mi.Name,
             Macro = $"{(Char)3}{(Char)3}{(Char)95}{att.GlobalName}{(Char)32}",
             MethodInfo = mi
         });
     }
     return rtn.OrderBy(c => c.AssemblyName).ThenBy(c => c.clsName).ThenBy(c => c.MethodName).ToList();

 }
 }

 public class MyRibbonCommand : ICommand
 {
     public event EventHandler CanExecuteChanged;

     public bool CanExecute(object parameter)
     {
         return true;
     }

     public void Execute(object parameter)
     {
         var ctl = parameter as Autodesk.Windows.RibbonCommandItem;
         Application.DocumentManager.MdiActiveDocument.SendStringToExecute(ctl.CommandParameter.ToString().TrimEnd() + " ", true, false, false);
     }
 }

调用方法

 var cmds = CMDHelper.GetAssemblyAutoCADCmds(ass);
 var assName= ass.GetName().Name; 
  MyRibbonTab myRibbonTab = new MyRibbonTab(cmds, assName, assName);

效果如下