在基於AutoCAD做二次開發時,常見的教程講的都是在DLL中定義一些自定義命令,然后通過netload命令加載這個DLL,通過執行自定義命令的方式來執行我們的自定義功能。這樣的方式在在學習中是顯得很簡單,但用在正式產品中就顯得太業余了,沒有專業精神。當然更professional的當然是和AutoCAD一樣,提供一些基於Ribbon的用戶界面來調用我們的自定義功能才好。多啰嗦一句,這個方法同樣適用基於AutoCAD的其他產品,比如Map 3D和Civil 3D。下面就講講如何實現創建Ribbon用戶界面。
首先了解一下Ribbon的概念,下圖是AutoCAD的一個Ribbon界面截圖,它有一些Tab組成,比如Home,Insert等等;在一個Tab里面又有不同的Panel組成,即豎線分割的部分;panel里面就是button了,這些button來執行具體的功能。不是很准確,我理解大概就是這樣回事了。:)
下面來通過程序創建一個tab,在這個tab里面加兩個panel,在panel里面放兩個button來執行自定義的AutoCAD命令。
新建一個class類庫工程,需要添加的引用包括:
acmgd
acdbmgd
acCoreMgd(對於AutoCAD 2013)
acCui
AcWindows
AdWindows
下面是代碼片段:
private const string MY_TAB_ID = "MY_TAB_ID"; [CommandMethod("addMyRibbon")] public void createRibbon() { Autodesk.Windows.RibbonControl ribCntrl = Autodesk.AutoCAD.Ribbon.RibbonServices.RibbonPaletteSet.RibbonControl; //can also be Autodesk.Windows.ComponentManager.Ribbon; //add the tab RibbonTab ribTab = new RibbonTab(); ribTab.Title = "My custom tab"; ribTab.Id = MY_TAB_ID; ribCntrl.Tabs.Add(ribTab); //create and add both panels addPanel1(ribTab); addPanel2(ribTab); //set as active tab ribTab.IsActive = true; } private void addPanel2(RibbonTab ribTab) { //throw new NotImplementedException(); } private void addPanel1(RibbonTab ribTab) { //throw new NotImplementedException(); }
通過這些代碼,應該已經可以創建一個空白的Tab,並把他設置當前活動Tab,如圖:
現在往這個Tab里面添加一個Panel,然后加入一個button來執行我的自定義命令。
private const string MY_TAB_ID = "MY_TAB_ID"; [CommandMethod("addMyRibbon")] public void createRibbon() { Autodesk.Windows.RibbonControl ribCntrl = Autodesk.AutoCAD.Ribbon.RibbonServices.RibbonPaletteSet.RibbonControl; //can also be Autodesk.Windows.ComponentManager.Ribbon; //add the tab RibbonTab ribTab = new RibbonTab(); ribTab.Title = "My custom tab"; ribTab.Id = MY_TAB_ID; ribCntrl.Tabs.Add(ribTab); //create and add both panels addPanel1(ribTab); addPanel2(ribTab); //set as active tab ribTab.IsActive = true; } private void addPanel2(RibbonTab ribTab) { //create the panel source RibbonPanelSource ribPanelSource = new RibbonPanelSource(); ribPanelSource.Title = "Edit Registry"; //create the panel RibbonPanel ribPanel = new RibbonPanel(); ribPanel.Source = ribPanelSource; ribTab.Panels.Add(ribPanel); //create button1 RibbonButton ribButtonDrawCircle = new RibbonButton(); ribButtonDrawCircle.Text = "My Draw Circle"; ribButtonDrawCircle.ShowText = true; //pay attention to the SPACE after the command name ribButtonDrawCircle.CommandParameter = "DrawCircle "; ribButtonDrawCircle.CommandHandler = new AdskCommandHandler(); ribPanelSource.Items.Add(ribButtonDrawCircle); } private void addPanel1(RibbonTab ribTab) { //throw new NotImplementedException(); } [CommandMethod("DrawCircle")] public void DrawCircle() { //畫個圓,實現在此略去,這不是這篇blog的重點。 }
注意上面的代碼中我定義了一個ribButtonDrawCircle,指定他的CommandParameter為我的自定義命令名“DrawCircle”,並且指定他的CommandHandler 是AdskCommandHandler。這里的AdskCommandHandler是一個自定義的類,需要實現System.Windows.Input.ICommand接口。實現的方法就是在Execute時把commandParameter發送到AutoCAD命令行窗口執行。代碼如下:
using System; using System.Collections.Generic; using System.Linq; using System.Text; using Autodesk.Windows; namespace AutoCAD_Debugger { class AdskCommandHandler : 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); } } } }
執行結果如下圖。注意如果你在測試是發現你的button只是把命令字符串發送到了AutoCAD命令行但沒有執行,必須按回車才能執行,那你多半是忽略了CommandParameter 后面那個空格!
好了,基本過程應該就是這樣,當然我們還可以為button添加圖標,讓他更好看一點。下來峻祁連將再介紹如何讓AutoCAD自動就自動加載這個Ribbon菜單,這個就更方便了,敬請期待。