In the last few posts I have outlined in great detail how to make a simple Revit Add-in using the IExternalCommand implementation. Doing that is a great and really fast way of adding new tools to Revit, but after a while we will realize that we just need a little more organization. Luckily for us Revit API offers a way to create our own tab in Revit and an array of different ways to add buttons to it. For the sake of keeping this tutorial simple and easy to follow, I will only show you how to convert our all-ready CurveTotalLength tool to a button.
In this post we will cover a few things like:
- IExternalApplication implementation
- new RibbonPanel
- new PushButton
- resource management
First let’s open our Visual Studio session that we worked on last week. It should look like this:
On the right hand side, in our Solution Explorer I will first change the name of the CurveTotalLength cs file from Class1.cs to CurveTotalLength.cs.
- Right click on Class1.cs
- Click on Rename and type in “CurveTotalLength.cs”
Now, let’s just “Build it” and we can close that file.
This was just a quick maintenance procedure to make sure that our file is named properly because next what we will do is import that file into a new Project in Visual Studio. Unfortunately there isn’t an easy way to just take an existing project in Visual Studio and rename it. The easiest way is to actually just create a new project and add an existing one to it if needed. At least that’s what I have been doing.
So let’s create a new project in Visual Studio. This step was described before here. We will call it GrimshawRibbon, but you can call it whatever you want – just remember that it’s not easy to rename the project folder structure after it was created.
Next, just like we discussed before we need to reference in Revit API and Revit APIUI libraries. Again, look at this link here.
Now, let’s just quickly rename the default Class1.cs to App.cs like so(see image above):
Click Yes, to confirm.
Next, let’s add our existing CurveTotalLength project to this solution (SHIFT + ALT + A). When the window pops up we need to navigate to our CurveTotalLength project location and look for CurveTotalLength.cs file. You should see a new file appear in your Solution Explorer like so:
Next let’s quickly add a new folder to our project and then move(drag and drop) the CurveTotalLength to that folder to keep our application nicely organized:
- Right click on our project.
- Hover over Add…
- Click on New Folder
Before we start implementing the IExternalApplication, we need to make sure that we have all of the “using” statements as well as one more assembly loaded (PresentationCore), that we will need to define an icon/image for our button.
- Right click on References in Solution Explorer, then click on Add Reference…
- Click on “Assemblies” on the left side.
- In search field type in “Presentation”.
- Select PresentationCore from the list.
- Click OK.
Now, that we have all of the assemblies needed*, we can get to implementing IExternalApplication. First let’s create a “road map” using pseudo code before we start filling in the blanks:
*You will notice that we also defined using System.Reflection in code below. System is loaded in by default so there was no need to add it in, and all we needed to do was just type “using System.Reflection” to start using methods defined in that assembly.
This is a basic outline for our method. We haven’t done any heavy lifting yet, but we have a good idea about what needs to be done. We already loaded in PresentationCore and I mentioned that we will need it to define an image for our button. Before we get to code and explain how to define that image, let’s create the image and load it into our project first: I usually make my images roughly 320 x 320 pixels. That’s too big for the icon (32 x 32), but it’s much easier to work with that in Illustrator or Photoshop. Save your image to PNG (with transparency) and then you can easily create a 32px icon version of the file using online service called ICO Converter. For a single push button, we need a 32 pixel image so these settings will be fine:
- Select a PNG file.
- Select pixel size needed
- Select Bit Depth
- Click Convert
Files will be automatically saved in our Downloads folder and will be called favicon.ico so all we need to do is rename that file to totalLength.png. You will be prompted if you want to change the file extension to PNG so please click yes to confirm. Now, let’s add it into our Visual Studio project. First create a new folder in our Solution Explorer and call it “Resources” then add our file like so:
- Right click on Resources folder
- Hover over Add
- Click on Existing Item…
- Select our image in the Solution Explorer
- Change Build Action to Resource
Our image is ready, so are all of the assemblies needed, so we can go ahead and define our method that will create the tab and a new button:
Let’s go over it line by line:
- This defines what kind of method we want to create. For our purpose a “static”, “void” method will suffice. Static means that we are creating a method that can be invoked without first creating an instance of its parent class. Void means that our method will not return anything.
- This will be the name displayed on our tab.
- Here we create an instance of a new tab with the given name.
- Here we create a new Panel which will be added to our Tab. We call this panel Tools.
- Here we use Reflection method called Assembly to get a path to folder that our application is being compiled to.
- Before we create a new PushButton we need to create a PushButtonData instance
- first input is a unique name/id for our new button
- this is text that will be displayed under our button. I wanted our name to be two lines hence the System.Environment.NewLine piece of code.
- this is a location of a dll that will be called when button is pushed
- this is the name of the method that will be called including a namespace.
- Here we add the new PushButton to our Panel.
- Here we define a tooltip message that will be displayed when user hovers over our button.
- Here we define a BitmapImage from the source. Bear in mind that it has to be defined as a URI source so we are creating a new instance of URI like so: new Uri(“pack://application:,,,/GrimshawRibbon;component/Resources/totalLength.png“) where “GrimshawRibbon” is the name of our current project followed by “;component” and then a “/Resources” which is the name of the folder we put our image into, then finally “/totalLength.png” which is the name of the file itself.
- Here we set the LargeImage property of the button to our image.
This is really the gist of our application. Just to make sure that it all makes sense here’s where our variable are coming from:
Now that we have a method defined that will create the tab, all we have to do is call it when our plug-in is loaded into Revit – every time Revit starts. Here’s the full code:
The last step before we can fire up Revit is making sure that we have a addin manifest file that will register our application with Revit. Just like we did in the previous tutorial let’s just add a new TextFile to our project and call it GrimshawRibbon.addin. You can reference the steps from here. Here’s the code for this addin file (it differs slightly from an ExternalCommand registration):
Make sure that you are changing the addin file Build Action to Content and its Copy to Output Directory to Copy if newer.
Now, if we build our project we should have two files, that we can copy to our Revit addins location. Again, if you don’t know where that is, please reference previous tutorials here. Truth is that you should really read the previous three tutorials before attempting this one. :-)
Now, if you fire up Revit, you will have something like this:
Adding your own tab will probably make you realize that having a whole new tab just for one tool is kind of meaningless and you will set out on the path to fill it up with things that will make your life as a Revit user that much more easier. I have been doing this for a few months now, but I am up to 15 custom tools that I created for our office. Some are really simple like the one we were working with during this tutorial series, and some are a little bit more involved. Either way, having your own toolbar in your favorite application will for sure give you at least a small reason to be proud of yourself.
Thanks for sticking it out with me. It has been a long tutorial, lots of steps involved, but if you got through then its all it matters. Also, if I have missed anything – forgot to post an important image, skipped an important step – please let me know.
You can download the final DLL files from here:GrimshawDT - GrimshawRibbon2016 (510 downloads)