Sharpener.Revit 1.0.2

dotnet add package Sharpener.Revit --version 1.0.2
                    
NuGet\Install-Package Sharpener.Revit -Version 1.0.2
                    
This command is intended to be used within the Package Manager Console in Visual Studio, as it uses the NuGet module's version of Install-Package.
<PackageReference Include="Sharpener.Revit" Version="1.0.2" />
                    
For projects that support PackageReference, copy this XML node into the project file to reference the package.
<PackageVersion Include="Sharpener.Revit" Version="1.0.2" />
                    
Directory.Packages.props
<PackageReference Include="Sharpener.Revit" />
                    
Project file
For projects that support Central Package Management (CPM), copy this XML node into the solution Directory.Packages.props file to version the package.
paket add Sharpener.Revit --version 1.0.2
                    
#r "nuget: Sharpener.Revit, 1.0.2"
                    
#r directive can be used in F# Interactive and Polyglot Notebooks. Copy this into the interactive tool or source code of the script to reference the package.
#:package Sharpener.Revit@1.0.2
                    
#:package directive can be used in C# file-based apps starting in .NET 10 preview 4. Copy this into a .cs file before any lines of code to reference the package.
#addin nuget:?package=Sharpener.Revit&version=1.0.2
                    
Install as a Cake Addin
#tool nuget:?package=Sharpener.Revit&version=1.0.2
                    
Install as a Cake Tool

Sharpener Revit API Tools

The tools in the Sharpener.Revit package are purpose built by a regular user of the Revit.API and Revit.API.UI assemblies. It identifies opportunities to make these libraries more enjoyable to use.

Note: Usage of this NuGet will require the referencing of the RevitAPI.dll and RevitAPIUI.dll. It does not come as a source for those binaries.

Further Note: This package currently only supports Revit 2026 but analysis has begun on how to abstract so that usage of this package can be more universal, but there are some abstraction concepts to consider.

Features

Ribbon Builders

Customizing the Revit ribbon can be tedious, but using the Sharpener.Revit.Ribbon tooling, your ribbon syntax can be more like this:

private static void BuildRibbon(UIControlledApplication uiApplication)
{
    RibbonTabBuilder
        .Create("Your Revit AddIn")
        .AddPanel("Main", panel => panel
            .AddPushButton<ToggleMain>("Dashboard", "Dashboard", button => button
                .WithIcon("Resources", "dashboard.png"))
        )
        .AddPanel("Content", panel => panel
            .AddPushButton<ToggleContentManager>("Content Manager", "Content Manager", button => button
                .WithIcon("Resources", "content.png"))
        )
        .AddPanel("Mechanical", panel => panel
            .AddPushButton<CreateCutLengths>("Cut Lengths", "Cut Lengths", button => button
                .WithIcon("Resources", "content.png"))
        )
        .AddPanel("Settings", panel => panel
            .AddPushButton<OpenSettingsWindow>("Settings", "Settings", button => button
                .WithIcon("Resources", "settings.png")))
        .Build(uiApplication);
}

Revit Theme

You can also sync your UI to the Revit theme

// in your constructor or something
uiApplication.SyncRevitTheme(this, options =>
{
    options.OnStartup = ApplySynchronizedTheme;
    options.OnUiThemeChanged = ApplySynchronizedTheme;
});

// what you subscribe to
private static void ApplySynchronizedTheme(DependencyObject dependencyObject)
{
    // everything inside ApplyTheme is not real (yet?), it's just a sample of how you'd do it.
    dependencyObject.ApplyTheme(UIThemeManager.CurrentTheme == UITheme.Dark ? Theme.Dark : Theme.Light);
}

Revit Panes

These controls are derived from System.Windows.Controls.Page and Autodesk.Revit.UI.IDockablePaneProvider and they take care of a lot of the boilerplate for you so that you do not need to register it or anything like that. Just create a class derived from this, then distribute it through your instance as needed (but I recommend dependency injection for lifetime scope simplification).

<panes:RevitPane x:Class="YourNameSpace.Controls.ContentPane"
                  # standard xaml declarations
                  xmlns:panes="clr-namespace:Sharpener.Revit.Controls.Panes;assembly=Sharpener.Revit">
    # your content
</panes:RevitPane>

Element Type Selection Filter

A generic selection filter that simplifies filtering by element type. Useful for avoiding redundant custom filters.

var selectedRef = uiDoc.Selection.PickObject(ObjectType.Element, new ElementTypeSelectionFilter<FamilyInstance>(), "Select a family instance to register");

Tryable External Command

Simplifies error handling in external commands by wrapping execution in a try-catch pattern. Focus on the logic, not the boilerplate.

/// <summary>
///     Upserts a family to a hypothetical family manager service.
/// </summary>
[TryableCommand]
[Transaction(TransactionMode.Manual)]
public class RegisterFamily : TryableExternalCommand
{
    protected override UiResult TryExecute(ExternalCommandData commandData, ref string message, ElementSet elements)
    {
        var uiApp = commandData.Application;

        // This might fail, but the base class handles exceptions
        var upsertResult = familyManagerService.PickAndUpsertContent(uiApp);
        return familyManagerService.HandleResult(uiApp, registrationResult, out message);
    }
}

External Event Manager

Simplifies the management of external events. Once registered (typically via dependency injection), you can raise events by handler type—no need for enums or manual mapping.

// Register the event
_externalEventManager.RegisterEvent(new FooEventHandler());

// Raise the event elsewhere
_externalEventManager.RaiseEvent<FooEventHandler>();

// Or bind to a WPF ICommand
ICommand FooCommand = new RelayCommand(() =>
    _externalEventManager.RaiseEvent<FooEventHandler>());

This approach reduces boilerplate and enables clean ICommand bindings in WPF view models.

Product Compatible and additional computed target framework versions.
.NET net8.0-windows7.0 is compatible.  net9.0-windows was computed.  net10.0-windows was computed. 
.NET Framework net481 is compatible. 
Compatible target framework(s)
Included target framework(s) (in package)
Learn more about Target Frameworks and .NET Standard.

NuGet packages

This package is not used by any NuGet packages.

GitHub repositories

This package is not used by any popular GitHub repositories.

Version Downloads Last Updated
1.0.2 121 9/2/2025
1.0.1 161 9/2/2025
1.0.0 113 9/2/2025