Custom Ribbon of Navisworks part 1

By Xiaodong Liang

A plug-in type called CommandHandlerPlugin has been introduced in Navisworks 2012. It allows you to create a plug-in with multiple commands, organize them in a custom tab that will be added to the ribbon user interface of the main product. It provides more sophistication than the basic AddInPlugin.

Overview

This plug-in has the following structure:

  • plug-in class

  • ribbon interface file (xaml)

  • name file for localization

 

This plug-in class provides attributes to specify the basic properties, ribbon interface file, name file for localization, ribbon tabs and commands. Several functions are usually overridden to execute the command, update the command specified by the command Id, or toggle the visibility of the ribbon tab etc. The ribbon interface file uses Extensible Application Markup Language (XAML) to configure the ribbon layout. The name file for localization defines the localized text (display name, tooltip etc) for ribbon tabs and commands.

 

To work with this plug-in, we first need to create a class dll. – In this article, C# is used as the programming language and the sample is named ADNRibbonDemo.

Download ADNRibbonDemo

Plug-In Class

This class must be derived from CommandHandlerPlugin.

Main plug-in attributes

Plugin: defines basic attributes such as name, developer ID etc.

[Plugin("ADNRibbonDemo", "ADSK", DisplayName = "ADNRibbonDemo")]

Strings: identifies the *.name file which defines the localized text for ribbon (see section Name File for Localization). e.g.
[Strings("ADNRibbonDemo.name")]

RibbonLayout: identifies an xaml file that defines the layout of associated custom ribbon(see section Ribbon Interface File). e.g.

[RibbonLayout("ADNRibbonDemo.xaml")]

RibbonTab: defines a ribbon tab. It must be accompanied by a RibbonLayout attribute in order for the tab to appear in the GUI. The attributes include:

  • Id: unique in the plug-in, and must correspond to the tab Id used in the xaml layout file.
  • DisplayName: The text to display for this Ribbon tab
  • LoadForCanExecute: if True, the plug-in is fully loaded to ensure that CanExecuteRibbonTab method is called. The method can be used to make a ribbon tab contextual i.e. only visible when specified conditions are met. Otherwise the tab is visible by default.
  • CallCanExecute: determines the conditions in which CanExecuteRibbonTab should be called

e.g.

[RibbonTab("ID_CustomTab_1", DisplayName = "Custom Tab 1 - non-localised")]
  • Command: defines a command that will perform an action within the application. The attributes include:
  • Id: unique in the plug-in and must correspond to the command Id used in the xaml layout file
  • DisplayName: The text to display for command
  • Icon: defines the standard image
  • LargeIcon: defines the large image used for the command
  • CanToggle: defines whether the button as it appears in the ribbon can toggle on and off.
  • ToolTip: text that will appear when the user hovers over the command
  • ExtendedToolTip: additional text that describes the purpose of the command
  • Shortcut: a keyboard shortcut that can be used to activate the command
  • CallCanExecute: determines the conditions in which CanExecuteCommand should be called. If the CanExecuteCommand is not called the default command state is disabled.
  • LoadForCanExecute: commands are enabled by default, but if this is False the plug-in will not be fully loaded until the first time a command is executed. If this is True the plug-in will be fully loaded at application startup in order to call the CanExecuteCommand method.

e.g.

[Command("ID_Button_1",Icon="One_16.ico", LargeIcon = "One_32.ico",
             CanToggle = true, DisplayName = "Button 1 non-localized")

Some attributes specified in the plug-in class can be overridden by the localized name file or ribbon interface file (xaml), such as display name, images, tooltip, extended tooltip.

Main plug-in overridden functions

ExecuteCommand: Executes a command when a button is pressed. It identifies the command by the Id defined in the command attribute. e.g.

public override int ExecuteCommand(string commandId,
                            params string[] parameters)
{
    switch (commandId)
    {
        case "ID_Button_1":
            {
                // the flag is used to 
                // set status of other commands
                m_toEnableButton = 
                    !m_toEnableButton;
                break;
            }
        // dropdown commands
        case "ID_Button_4":
        case "ID_Button_5":
            {
                MessageBox.Show("he command with ID is clicked = '" 
                    + commandId + "'");
                break;
            }
    }
    return 0;
}

CanExecuteCommand: updates the command specified by the command Id. The argument CommandState indicates if the command is enabled, checked (if a toggle command) and visible. e.g.

public override CommandState CanExecuteCommand(String commandId)
{
    CommandState state = new CommandState();
    switch (commandId)
    {
        case "ID_Button_3":
            {
                // button3 is disabled/enabled by a flag
                state.IsEnabled = m_toEnableButton;
                break;
            }
        default:
            {
                // other commands are all visible and enabled
                state.IsVisible = true;
                state.IsEnabled = true;
                state.IsChecked = false;
                break;
            }
    }
    return state;
}

CanExecuteRibbonTab: The return flag will tell if display the corresponding tab or not.

public override bool CanExecuteRibbonTab(String ribbonTabId)
{
    // The second ribbon tab is visible or not
    // by Button 2 toggles on/off
    if (ribbonTabId.Equals("ID_CustomTab_2"))
    {
        return m_toShowTab;
    }
    return true;
}

In our sample, we define two tabs. Tab1 contains two panels (called Panel1 and Panel2). Panel1 has Button1 of large size. Panel2 has two buttons of small size (called Button2 Button3). Tab2 has one panel with two commands (called Button4, Button5), grouped as dropdown menu. Button1 enables/disables Button3. Button2 toggles the visibility of Tab2 to be on or off.

(To be continued)


Comments

9 responses to “Custom Ribbon of Navisworks part 1”

  1. Xiaoxuan Avatar
    Xiaoxuan

    Hi Xiaodong,
    I just follow your post and get your solution file down hoping i could create a custom tab to host custom buttons. However, it doesn’t work. I am using navisworks 2018 sdk. and the error i get is “NWRibbonButton doesnot exist in gui.roamer”. Do you have any hint? I just need to creat very simple tab. Don’t need to have the fancy switch in there. If there any other tutorial i could refer to as well?

  2. Xiaodong Liang Avatar
    Xiaodong Liang

    Hi Xiaoxuan,
    probably this sample will need to be updated. Please use SDK sample CustomRibbon. It works well at my side. By that sample, you could check which is missing or updated in the new releases. As far as I know, no change, but in case something I do not know.

  3. Joemar Mante Avatar
    Joemar Mante

    Hello,
    I don’t know if this is the right place, but how can we retrieve the quantities in a Navisworks Quantification workbook? We are able to read/write to Item Catalogs and Resource Catalogs using a custom Navisworks plugin but after we sketch our markups we dont know which objects/methods to call to extract the calculated quantities. The example C# code that came with the SDK also does not have this as well.
    Thanks in advanced.
    Cheers,
    Joemar

  4. Eugen Lipes Avatar
    Eugen Lipes

    This sample DEFINITLY need to be updated.
    And recommended sample in SDK sample CustomRibbon too.
    1. CustomRibbon.xaml shows a lot of errors like

  5. Eugen Lipes Avatar
    Eugen Lipes

    This sample DEFINITLY need to be updated.
    And recommended sample in SDK sample CustomRibbon too.
    1. CustomRibbon.xaml shows a lot of errors like
    The name NwRibbonButton does not exist in the namespace
    Type RibbonControl does not support direct content
    2. Plugin added to Plugins folder, but no changes in the ribbon detected.
    Is it some stealth-plugin? With no wisual effects? (sarcasm)

  6. Hello,
    Is it possible to customize the Ribbon Tab and the buttons of a class derived of AddInPlugin instead of a CommandHandlerPlugin?
    Reference:
    public class DumpTimelinerTasks : AddInPlugin
    The question is because I need to perform some tasks that can only be done in AddInPlugin but the Ribbon Tab and buttons don’t seem to change as they do when the class derives from CommandHandlerPlugin.
    Need an answer and best regards

  7. Xiaodong Liang Avatar
    Xiaodong Liang

    Hi JMGP,
    AddInPlugin is grouped by Navisworks. It can only locate on several locations: AddIn Tab, Context menu, Export menu etc.
    The other blog might probably help you:
    http://adndevblog.typepad.com/aec/2016/01/add-custom-panel-and-button-to-built-in-tab-of-navisworks-ribbon.html

  8. Ivelin Evtimov Avatar
    Ivelin Evtimov

    Hi,
    How to override the ExtendedToolTip in the xaml file?

  9. I followed all the above steps provided by you but still getting the same error mentioned by you.”NWRibbonButton doesnot exist in gui.roamer”. I am using navisworks 2023 sdk. is there any solution you found? any related links?

Leave a Reply

Discover more from Autodesk Developer Blog

Subscribe now to keep reading and get access to the full archive.

Continue reading