Add a new custom Ribbon Panel to a Revit built-in tab

Add a new custom Ribbon Panel to a Revit built-in tab

Anonymous
Not applicable
8,835 Views
8 Replies
Message 1 of 9

Add a new custom Ribbon Panel to a Revit built-in tab

Anonymous
Not applicable

Hi,

 

What is the difference between Autodesk.Revit.UI.RibbonPanel and Autodesk.Windows.RibbonPanel? I see Autodesk.Windows namespace provides more functions than to Autodesk.Revit.UI to add new custom menus.

 

Here is my code to add a new custom Ribbon Panel to an existing Revit tab, View for example:

 

var button = new Autodesk.Windows.RibbonButton
{
	Text = "My Button",
	ShowText = true
};
var panelSource = new Autodesk.Windows.RibbonPanelSource
{
	Title = "My Panel"
};
panelSource.Items.Add(button);
var panel = new Autodesk.Windows.RibbonPanel
{
	Source = panelSource
};
// Get View tab
string tabName = "View";
RibbonTabCollection tabs = Autodesk.Windows.ComponentManager.Ribbon.Tabs;
foreach (Autodesk.Windows.RibbonTab tab in tabs)
{
	if (tab.Name == tabName)
	{
		tab.Panels.Add(panel);
		break;
	}
}

However, this code does not work. No new panel will be added to the View tab. I don't want to add my plugin button to the Add-Ins tab like normally use. Is there any way to customize an existing Revit tab and its children panels?

 

Thanks,

Khoa

 

0 Likes
Accepted solutions (1)
8,836 Views
8 Replies
Replies (8)
Message 2 of 9

Anonymous
Not applicable

It can be done, it's a bit of work and is likely to break at any time (unsupported feature and all that).

 

The basic idea is to create your panels and buttons using the API in the normal way and then shift them over to the system tabs using the Autodesk.Windows features.

 

Jeremy was kind enough to publish my proof of conept for this on his blog at: http://thebuildingcoder.typepad.com/blog/2014/07/moving-an-external-command-button-within-the-ribbon...

 

There's some example code there that should get you on the path to what you need.

 

Also here's a related forum post: http://forums.autodesk.com/t5/revit-api/add-button-to-existing-ribbon-panel/m-p/4981498

 

 

Edit: I just noticed that the dropbox link on Jeremy's page for my demo project is dead. I'll upload it to this thread later when I get home from work.

Message 3 of 9

jeremytammik
Autodesk
Autodesk

... and I can upload the sample material directly to The Building Coder and replace the dead link with a live one that is hopefuly more reliable.

 

Cheers,

 

Jeremy



Jeremy Tammik
Developer Technical Services
Autodesk Developer Network, ADN Open
The Building Coder

0 Likes
Message 4 of 9

Anonymous
Not applicable

Hi Scott,

 

I learned a lot from your previous post and see there is a restriction to customize the Revit system menu. So we will go in the unofficial way.

 

Based from you code in Jeremy's blog, I rewrote the code but it still does not move the existing custom panel to a system ribbon tab:

 

public class Application : IExternalApplication
{
    private string _ribbonPanelName = "MyRibbonPanel";

    public Result OnStartup(UIControlledApplication application)
    {
        // Add a new ribbon panel to Revit Add-Ins tab
        Autodesk.Revit.UI.RibbonPanel ribbonPanel = application.CreateRibbonPanel(_ribbonPanelName);
        string location = Assembly.GetExecutingAssembly().Location;

        var pushButtonData = new PushButtonData(
            "MyApp_Browser_Command",
            "MyApp",
            location,
            "MyApp.ShowWindow");
        pushButtonData.AvailabilityClassName = "MyApp.ShowWindow";

        PushButton button = ribbonPanel.AddItem(pushButtonData) as PushButton;

        application.ControlledApplication.ApplicationInitialized += ControlledApplication_ApplicationInitialized;

        return Result.Succeeded;
    }

    private void ControlledApplication_ApplicationInitialized(object sender, Autodesk.Revit.DB.Events.ApplicationInitializedEventArgs e)
    {
        Autodesk.Windows.RibbonPanel ribbonPanel = null;
        bool isBreak = false;
        // Move custom ribbon panel from Add-Ins to View tab
        string tabName = "View";
        RibbonTabCollection tabs = Autodesk.Windows.ComponentManager.Ribbon.Tabs;
        foreach (Autodesk.Windows.RibbonTab tab in tabs)
        {
            if (tab.Id == "Add-Ins")
            {
                foreach (Autodesk.Windows.RibbonPanel panel in tab.Panels)
                {
                    // Get this custom ribbon panel in Add-Ins tab
                    if (panel.Source.AutomationName == _ribbonPanelName)
                    {
                        ribbonPanel = panel;
                        isBreak = true;
                        break;
                    }
                }
                if (isBreak) break;
            }
        }
        if (ribbonPanel != null)
        {
            foreach (Autodesk.Windows.RibbonTab tab in tabs)
            {
                if (tab.Id == tabName)
                {
                    // Add this custom ribbon panel to a Revit system tab
                    tab.Panels.Add(ribbonPanel);
                    break;
                }
            }
        }
    }
}

I checked on VS Debugger and saw the code went through without errors. The ribbon panel was created and then added to the View system tab. However, I get notice that the new added panel is Autodesk.Windows.RibbonPanel, while other existing panels in the system ribbon tab are UIFramework.RvtRibbonPanel. Please see the attached image. I am not sure that difference may make the issue, but it is a suspect to think of.

 

Thanks.

 

0 Likes
Message 5 of 9

Anonymous
Not applicable

I've attached the demo solution. Compile that unaltered and see whether it works (there's an addin config file in the project folder ready to go).

 

Jeremy: thanks in advance for re-uploading the solution files to your blog. Sorry, I cleaned out my public dropbox folder a few weeks back and forgot that you had that file directly linked 🙂

0 Likes
Message 6 of 9

Anonymous
Not applicable
Accepted solution

Hi Scott,

 

Your demo solution works, to add a new button to the Manage tab. However, it does not add the ribbon panel, it adds items from this ribbon panel.

 

In fact, the code to add a new panel to a system ribbon tab does not work. It seems Revit prevents it. We can only add ribbon items to an existing ribbon panel of a system tab.

 

I rewrote the code to make it more generic to reuse:

 

public class Application : IExternalApplication
{
    private string _ribbonPanelName = "MyPanel";

    public Result OnStartup(UIControlledApplication application)
    {
        AddRibbonItems(application);
        application.ControlledApplication.ApplicationInitialized += ControlledApplication_ApplicationInitialized;
        return Result.Succeeded;
    }

    public Result OnShutdown(UIControlledApplication application)
    {
        return Result.Succeeded;
    }

    private void ControlledApplication_ApplicationInitialized(object sender, Autodesk.Revit.DB.Events.ApplicationInitializedEventArgs e)
    {
        MoveRibbonItemsBetweenTabPanels("Add-Ins", _ribbonPanelName, "View", "Windows");
    }

    private void AddRibbonItems(UIControlledApplication application)
    {
        // Add a new ribbon panel to Revit Add-Ins tab
        Autodesk.Revit.UI.RibbonPanel ribbonPanel = application.CreateRibbonPanel(_ribbonPanelName);
        // Create ribbon items for this ribbon panel
        string location = Assembly.GetExecutingAssembly().Location;
        var pushButtonData = new PushButtonData(
            "MyApp_Browser_Command",
            "MyApp",
            location,
            "MyApp.ShowWindow");
        pushButtonData.AvailabilityClassName = "MyApp.ShowWindow";
        PushButton button = ribbonPanel.AddItem(pushButtonData) as PushButton;
    }

    private void MoveRibbonItemsBetweenTabPanels(
        string sourceTabName,
        string sourcePanelName,
        string targetTabName,
        string targetPanelName)
    {
        try
        {
            Autodesk.Windows.RibbonPanel sourceRibbonPanel = null;
            bool isBreak = false;
            RibbonTabCollection tabs = Autodesk.Windows.ComponentManager.Ribbon.Tabs;
            // Get source ribbon panel
            foreach (Autodesk.Windows.RibbonTab tab in tabs)
            {
                if (tab.Id.Equals(sourceTabName, StringComparison.OrdinalIgnoreCase))
                {
                    foreach (Autodesk.Windows.RibbonPanel panel in tab.Panels)
                    {
                        if (panel.Source.AutomationName.Equals(sourcePanelName, StringComparison.OrdinalIgnoreCase))
                        {
                            sourceRibbonPanel = panel;
                            // Remove this panel of out its ribbon tab
                            tab.Panels.Remove(panel);
                            isBreak = true;
                            break;
                        }
                    }
                    if (isBreak) break;
                }
            }
            // Copy items from this source ribbon panel to another ribbon panel (in different tab)
            if (sourceRibbonPanel != null)
            {
                foreach (Autodesk.Windows.RibbonTab tab in tabs)
                {
                    if (tab.Id.Equals(targetTabName, StringComparison.OrdinalIgnoreCase))
                    {
                        //tab.Panels.Add(sourceRibbonPanel); // Not work
                        foreach (Autodesk.Windows.RibbonPanel panel in tab.Panels)
                        {
                            if (panel.Source.AutomationName.Equals(targetPanelName, StringComparison.OrdinalIgnoreCase))
                            {
                                // Copy source items to target panel
                                foreach (Autodesk.Windows.RibbonItem ribbonItem in sourceRibbonPanel.Source.Items)
                                {
                                    panel.Source.Items.Add(ribbonItem);
                                }
                                break;
                            }
                        }
                        break;
                    }
                }
            }
        }
        catch (Exception)
        {
        }
    }
}

 

This code was tested to work on Revit 2014/2015. It will create a new custom button on the View tab, Windows panel.

 

Thanks.

Message 7 of 9

Anonymous
Not applicable
That's intetesting. I tested it just before posting and it added both the
panel to the far right of the manage tab and the button by itself to an
existing panel.

Which version of Revit are you working with? I tested using 2015 R2.
0 Likes
Message 8 of 9

Anonymous
Not applicable

I see only "New Button" on Settings panel, no new custom panel at the far right of this Manage tab. It is only one, not both to show.

 

However, I try to update the ribbon control after adding the custom panel, but it does not work neither.

 

sourceRibbonPanel.Tab.RibbonControl.UpdateLayout();
sourceRibbonPanel.Tab.RibbonControl.StartBackgroundTabRendering();

 

I think it may be older Revit versions do not support this feature. I am using the original Revit 2014/2015:

 

Revit 2014 - build 20130308_1515
Revit 2015 - build 20140606_1530

 

0 Likes
Message 9 of 9

MiguelVJC82W
Enthusiast
Enthusiast

I've gotten this to work but for some reason I get an error message and the button is grayed out.

0 Likes