3 自己的工具按鈕
上次的例子只能在“附加模塊”→“外部工具”下運行,用作個人作品是沒問題,如果打算搞個公司產品的話,估計BOSS是不會滿意的。這次我來做一個直接顯示在“附加模塊”選項卡上的工具按鈕。
3.1 基礎
1、新建一個項目WelcomeToRevit。添加引用RevitAPI.dll和RevitAPI.dll。具體做法和上次一樣,不贅述。
2、保留指令
using System;
添加指令
using Autodesk.Revit.DB;
using Autodesk.Revit.UI;
using Autodesk.Revit.Attributes;
3、把默認生成的public class Class1{}改成
public class Class1: IExternalApplication{}
4、在public class Class1: IExternalApplication{}內部添加兩個函數OnStartup(UIControlledApplication application){}和OnShutdown(UIControlledApplication application){},分別用Result加以約束,並設定返回值為Succeeded。
5、在OnStartup(UIControlledApplication application){}內添加以下內容:
RibbonPanel ribbonPanel = application.CreateRibbonPanel("演示");
PushButtonData buttonData = new PushButtonData("cmdWelcomeToRevit","歡迎",@"C:\RevitBlog\Projects\WelcomeToRevit\WelcomeToRevit\bin\Debug\WelcomeToRevit.dll","WelcomeToRevit.Class2");
PushButton pushButton = ribbonPanel.AddItem(buttonData) as PushButton;
pushButton.ToolTip = "歡迎來到Revit。";
6、在命名空間WelcomeToRevit內部(不是Class1內部)添加一個類Class2,繼承於IExternalCommand接口類。在該類前面添加[Transaction(TransactionMode.ReadOnly)],在入口函數里添加內容TaskDialog.Show("RevitDemo", "Welcome To Revit!");並返回Succeeded。
7、完成后的代碼如下:
1 using System; 2 using Autodesk.Revit.DB; 3 using Autodesk.Revit.UI; 4 using Autodesk.Revit.Attributes; 5 6 namespace WelcomeToRevit 7 { 8 public class Class1: IExternalApplication 9 { 10 public Result OnStartup(UIControlledApplication application) 11 { 12 RibbonPanel ribbonPanel = application.CreateRibbonPanel("演示"); 13 14 PushButtonData buttonData = new PushButtonData("cmdWelcomeToRevit","歡迎",@"C:\Test\WelcomeToRevit\WelcomeToRevit\bin\Debug\WelcomeToRevit.dll","WelcomeToRevit.Class2"); 15 PushButton pushButton = ribbonPanel.AddItem(buttonData) as PushButton; 16 17 pushButton.ToolTip = "歡迎來到Revit。"; 18 19 return Result.Succeeded; 20 } 21 public Result OnShutdown(UIControlledApplication application) 22 { 23 return Result.Succeeded; 24 } 25 } 26 27 [Transaction(TransactionMode.ReadOnly)] 28 public class Class2 : IExternalCommand 29 { 30 public Result Execute(ExternalCommandData commandData, ref string message, ElementSet elements) 31 { 32 TaskDialog.Show("RevitDemo", "Welcome To Revit!"); 33 return Result.Succeeded; 34 } 35 } 36 }
仔細對比一下上個例子,會發現只是多了從8行到25行這一段。
8行,聲明一個類,繼承自RevitAPI的IExternalApplication(外部程序)接口。與IExternalCommand不同,IExternalApplication用兩個成員函數OnStartup和OnShutdown來對應啟動和關閉狀態。
10行,重載OnStartup函數。
12行,實例化對象RibbonPanel,並通過CreateRibbonPanel方法新建一個面板,這個面板是用來承載按鈕的,面板下方顯示“演示”字樣。
14行,實例化對象PushButtonData,並通過構造函數新建一個按鈕數據。該構造函數有四個參數:第一個是程序內部使用的按鈕名稱,這個只要注意不要重名就可以;第二個是用戶可見的按鈕文字,這個可以自己隨便寫;第三個是按鈕對應的類庫地址,即dll的路徑,要按實際的填;第四個是按鈕命令實現代碼的類名,這里要和28行對應。其中第三個參數前面的@用來忽略后面的轉義字符“\”,這是個很實用的小技巧。
15行,根據按鈕數據實例化對象PushButton,並把這個按鈕添加到面板上。
17行,給按鈕添加一個提示,當鼠標停在上面時會出現相應提示。
8、編寫WelcomeToRevit.addin復制到revit插件目錄下。
1 <?xml version ="1.0" encoding ="utf-8" standalone ="no"?> 2 <RevitAddIns> 3 <AddIn Type="Application"> 4 <Assembly> 5 C:\test\WelcomeToRevit\WelcomeToRevit\bin\Debug\WelcomeToRevit.dll 6 </Assembly> 7 <AddInId>86394068-436d-4d15-ba53-96eefd77252c</AddInId> 8 <Name>WelcomeToRevit</Name> 9 <FullClassName>WelcomeToRevit.Class1</FullClassName> 10 <VendorId>NAME</VendorId> 11 </AddIn> 12 </RevitAddIns>
對比上個例子,有幾點不同:
<AddIn Type>標簽由"Command"變成"Application",表明本插件是外部應用而不是外部命令。
沒有<Text>標簽,這個標簽對外部應用不起作用。
增加<Name>標簽,為插件指定一個名字,這個標簽只用於外部應用。
3.2 美化
測試一下剛完成的插件,這次在“附加模塊”里出現了獨立的按鈕,執行后彈出對話框,不過沒有圖片,看上去不夠美觀。接着我來個它添加圖片。
1、在本插件所在目錄下建立一個文件夾,丟一個圖片文件進去。
2、在項目中添加引用WindowsBase、PresentationCore和System.Xaml(都是框架)。
3、添加指令using System.Windows.Media.Imaging;
4、在OnStartup函數里添加如下內容:
Uri uri = new Uri(@"C:\test\WelcomeToRevit\WelcomeToRevit\bin\Debug\images\wtr.png");
BitmapImage bitmapImage = new BitmapImage(uri);
pushButton.LargeImage = bitmapImage;
也可以直接寫成
pushButton.LargeImage = new BitmapImage(new Uri(@"C:\test\WelcomeToRevit\WelcomeToRevit\bin\Debug\images\wtr.png"));
重新編譯生成,執行后看到按鈕有圖片了。
簡單解釋一下:
Autodesk.Revit.UI的PushButton有個參數LargeImage用來定義按鈕圖片,但這個參數的類型是BitmapImage,不能直接接收Image類型,所以要通過Uri來轉換。
3.3 進階
其實上面的代碼還是有缺陷的,就是把插件和按鈕圖片的路徑在程序里寫死了,這樣很不靈活。所以我還要改一下。
1、添加指令using System.Reflection;
2、在定義按鈕數據的語句前加上string thisAssemblyPath = Assembly.GetExecutingAssembly().Location;用以獲取程序路徑。
3、把定義按鈕數據的語句改成PushButtonData buttonData = new PushButtonData("cmdWelcomeToRevit","歡迎",thisAssemblyPath,"WelcomeToRevit.Class2");就是替換掉第三個參數。
插件路徑的問題解決了,再來看按鈕圖片的問題。小火車公布的源碼用的是Replace方法,用圖片文件名替換掉dll文件名,但它把dll文件名寫死了,所以還是不夠靈活,所以我用另一個方法。
4、添加指令using System.IO;
5、在定義Uri的語句前加上string imagePath = Path.GetDirectoryName(thisAssemblyPath) + @"\images\wtr.png";
6、把定義Uri的語句改成Uri uri = new Uri(imagePath, UriKind.RelativeOrAbsolute);
最終代碼如下:
1 using System; 2 using System.IO; 3 using System.Reflection; 4 using System.Windows.Media.Imaging; 5 using Autodesk.Revit.DB; 6 using Autodesk.Revit.UI; 7 using Autodesk.Revit.Attributes; 8 9 namespace WelcomeToRevit 10 { 11 public class Class1: IExternalApplication 12 { 13 public Result OnStartup(UIControlledApplication application) 14 { 15 RibbonPanel ribbonPanel = application.CreateRibbonPanel("演示"); 16 17 string thisAssemblyPath = Assembly.GetExecutingAssembly().Location; 18 PushButtonData buttonData = new PushButtonData("cmdWelcomeToRevit","歡迎",thisAssemblyPath,"WelcomeToRevit.Class2"); 19 PushButton pushButton = ribbonPanel.AddItem(buttonData) as PushButton; 20 21 pushButton.ToolTip = "歡迎來到Revit。"; 22 23 string imagePath = Path.GetDirectoryName(thisAssemblyPath) + @"\images\wtr.png"; 24 25 Uri uri = new Uri(imagePath, UriKind.RelativeOrAbsolute); 26 BitmapImage bitmapImage = new BitmapImage(uri); 27 pushButton.LargeImage = bitmapImage; 28 29 return Result.Succeeded; 30 } 31 public Result OnShutdown(UIControlledApplication application) 32 { 33 return Result.Succeeded; 34 } 35 } 36 37 [Transaction(TransactionMode.ReadOnly)] 38 public class Class2 : IExternalCommand 39 { 40 public Result Execute(ExternalCommandData commandData, ref string message, ElementSet elements) 41 { 42 TaskDialog.Show("RevitDemo", "Welcome To Revit!"); 43 return Result.Succeeded; 44 } 45 } 46 }
3.4 總結
本例主要有如下知識點:
1、外部應用類型插件的基本寫法和相應配置文件的基本寫法。
2、在“附加模塊”選項卡里添加按鈕。
3、給按鈕添加圖片。
4、使用相對路徑。
