C# + Revit API: Lesson 8 - Tooltips & Icons - Extension Methods

1. Base Command Name // Command namespace guRoo.Cmds_GroupName //Command Class guRoo.Cmds_GroupName.Cmd_CommandName // Preferred method: GroupName GroupName._CommandName // The Approach we will use: guRoo.Cmds_GroupName.Cmd_CommandName // Remove guRoo.Cmds_ GroupName.Cmd_CommandName // Remove .Cmd GrouName_CommandName Or you can make things even more resilient by using: typeof(CommandName).FullName How to Name my Resources Tooltipkey = base name GroupName GroupName_CommandName Icons: GroupName## GroupName_CommandName## => Resolution in pixels (16 / 32px) How we will manage Tooltips We will create a Resources (resx) file in C# and embed this into our project. It will be available in memory for our project whilst it runs to access. We will store the tooltip and description as a dictionary of keys and values. ...

August 8, 2025 · 2 min

C# + Revit API: Lesson 7 - Introduction to Classes

1. Introduction Sneak Peak - Project Structure Commands Extensions Forms General Resources Utilities These are folders which contain various files that our toolbar will utilize. Note that these are not necessarily aligned with namespaces (which will be covered later) 2. What is a Class? In C#, classes are templates related to the creation and management of objects. There are many predefined classes available in C# and the Revit API. We use them for a wide range of things and will regularly be creating and developing our own classes. Accessing properties / methods of a Class Property: object.Property Method: Object.Method(argument1, argument2, etc) Namespaces When we create classes, we first tell them where they belong in our project. Namespaces can be nested within others using a dot separator, eventually tied back to our .addin namespace. // Revit API using Autodesk.Revit.Attributes; using Autodesk.Revit.UI; // geeWiz using geeWiz.Extensions; using geeWiz = geeWiz.Forms; using geeWiz = geeWiz.Utilities.Workshare_Utils; // The class belongs to the Commands namespace namespace geeWiz.Cmds_Audit { // Cmd_DeletePatterns // Cmd_PurgeRooms // Cmd_PurgeTemplates // Cmd_PurgeFilters } Basic Class Anatomy modifers class ClassName : Interface(s) Constructor (optional) Properties (optional) Methods (optional) Access modifiers control how this code can be accessed inside and outside your project. You will typically need to declare at least on of public/private, And sometimes static for the purposes we will use them for early on. Static Modifier The static access modifier is a difficult concept to grasp at first, so we will simplify it somewhat. Classes with a static modifier do not support the creation of objects of that class (instantiated). We commonly take advantage of this to create classes which behave more like toolkits, where the class itself acts more like a singe object we can call upon to do things for us. So basically, the `STATIC` modifier is one instrument that you could use to build a complex script with. Public and Private Modifier The public modifier lets you access something anywhere in your project. The private modifier limits access to the same class instead (generally for behind-the-scenes code in the class itself). There are other modifiers, but let’s keep it simple. ...

August 8, 2025 · 10 min

C# + Revit API: Lesson 6 - try & catch Statements

Pseudocode try { try to do this; } catch { if try gets exception, rollback and do this; } Exceptions Exceptions come in many forms and Revit API Docs typically specifies the types of Exceptions we can catch for its methods. There are also system type exceptions. catch // Exception as "e" to print the error { To catch a specific exceptions, catch as e; } catch { To catch all exceptions, do this; // but better to catch specific exceptions, // otherwise you will catch all necessary and unecessary exceptions. } finally { To run a final code regardless of outcome; } Use Don’t Abuse When you first begin using languages, try statements seem great - you can write code, and if you make a mistake your code can continue. THIS IS WRONG! ...

August 8, 2025 · 2 min

C# + Revit API: Lesson 5 - `if` Statements

if // Condition { run if condition is true; } else // If we have no false outcome -> we can skip 'else' branch altogether { run if condition is false; } else if Statement if // Condition { run if condition is true; } else if // Condition { run if there are more conditions; } else // If we have no false outcome -> we can skip 'else' branch altogether { run if condition is false; } Shorthand if Statements value = condition?then:else; Nearly always used for quickly setting another variable to one of two possibilities, using a conditional outcome. Only used if it’s a simple one liner task. ...

August 6, 2025 · 2 min

C# + Revit API: Lesson 4 - Logical Operators

They control logic and flow in our tools. We will have a good understanding of core statements we can use to build Revit Add-ins. Logical Operators x == y => true if x is equal to y x != y => true if x is not equal to y x > y => true if x is greater than y x < y => true if x is less than y x >= y => true if x greater than or equals to y x <= y => true if x less than or equals to y ...

August 6, 2025 · 2 min

C# + Revit API: Lesson 3 - Fundamental Types of Data in C#

Boolean bool true (1) false (0) Integer int Whole number: 1, 2, 3, etc. Numbers come in different formats but by default they are signable (can be negative). Typically, they use 32 bits based. Double double Decimal number: 0.0, 1.5, 6.592, -5.00, etc. Doubles use 64 bits, and are more common than floats (which use half - 32 bits). In Revit you will typically work with int and double. Characters char ‘a’, ‘b’, ‘c’, etc. ...

August 6, 2025 · 4 min

C# + Revit API: Lesson 2 - Bits & Bytes, ASCII Table, Pointers & Structs - Programming 101

I suggest taking CS50 Course to understand the basics of Programming True & False 0 and 1 Base 2 numbering system 1 0 1 x x x 4 2 1 = 5 In other words: 2 2 2 x x x 2 1 0 4 2 1 = 5 1 0 1 We call these bits Eight bits = 1 byte Memory is addressed into bytes ASCII Tables bring meaning to what various bytes represent: ASCII 48 = 0 (00) 110000 1 * 2^4 = 16 1 * 2^5 = 32 16 + 32 = 48 48 = 0 (in ASCII Table) Pointers = Structs (in C) Pointers are hexadecimal based values that identify an address in computer memory. ...

August 6, 2025 · 4 min

C# + Revit API: Lesson 1 - A Simple Walkthrough of the Command

This post explains one concrete command—line by line—so a beginner can follow without extra abstractions. What this command does when you click your add-in button: Tries to create a sheet (using an invalid title block on purpose → shows how error handling works). Collects up to 10 existing sheets and formats their numbers/names. Displays the result in a WPF dialog via a ViewModel. ✅ This article focuses only on the command. It assumes you’ve already wired a ribbon button (and .addin) that triggers StartupCommand. ...

August 6, 2025 · 4 min

C# + Revit API: Lesson 0

Why C#? Scalability Start with: Install Visual Studio 2022 Community Install .NET SDKs (.NET4.8 & .NET8) Install Nice3Point Templates Solution Start a solution / project Create a new project Choose the Revit Addin (Nic3Point) Template Configure your new project Name of the project Location Solution Name - same as project name (it’s a folder name that holds many projects) Additional Information Add-in type -> Application User Interface -> None IoC -> Disabled Serilog support -> unchecked Explore Visual Studio Properties & Solution Explorer (Project Browser in Revit) Error & Output CSProj -> Preconfigured up to Revit v.2025 .addin -> Change GUID (The rest we will change later) Application Class: Tells your addin how to begin and how to finish when Revit opens and closes. Class: External Application Method: OnStartup() Will run “Create Ribbon()” Creates a Panel Adds a PushButton to that Panel With 2 Icons Our Application OnStartup When it begins, it calls a Function “CreateRibbon()” And CreateRibbon is a defined function below that: Creates a panel This is possible due to pre-configured Revit API that we are using CreatePanel - is a pre-defined method under Revit API that, you guessed it, Creates a Panel in Revit. Creates a button Same for the Button AddPushButton Method in Revit API - Creates a button Commands Folder Core Code Currently: Task Dialog - Shows the name of the addin ExternalCommand, but we should use IExternalCommand This is the part that writes the logic for your button Once you click the button, whatever is under Commands Folder connected to the button will be executed. If you change the TaskDialog.Show(Document.Title, “Hello World”); Once you press the button in Revit it would show “Hello World” Resources: Icons Everything is saved in windows explorer Configurations: Debug and Release Per Revit Version from R20 to R25 References: Under: This PC > Windows (C:) > Program Files > Autodesk > Revit [2025]. DLL Files that you can reference to your project to build something. You could even add an excel package to work with Excel, will do that later. Build and test the first plugin Build the solution by clicking on Run (Play Button) next to Any CPU. Lauches Revit (Version that you pre-configured) Always Load your Addin What happened behind the scenes: VS2022 Added the DLL file and the .addin file into the right folder and launched Revit version that you specified with the Plugin loaded into Revit. That became possible due to preconfigured Visual Studio Nic3Point Template that you ran earlier. Everything is already set and pathed for you for the ease of starting and launching plugins. Go to New Project Find your new panel in the panel tabs on the top of Revit User Interface. Find your Addin / Plugin Click on it And you will get a message with the name of your Tool. Stop Debug Closes Revit & Debug Mode These tutorials were inspired by the work of Aussie BIM Guru. If you’re looking for a deeper dive into the topics, check out his channel for detailed explanations. ...

August 6, 2025 · 3 min