Announcements

Starting in December, we will archive content from the community that is 10 years and older. This FAQ provides more information.

ContextualHelp for RibbonButton. C#

Niko_Davydov
Advocate
Advocate

ContextualHelp for RibbonButton. C#

Niko_Davydov
Advocate
Advocate

Hi,

I have a question about Autodesk.Windows.RibbonButton.

I want to add buttons to the "Modify" panel, but I was only able to add an Autodesk.Windows.RibbonButton, not a PushButton.
Now, I want to add an F1 link to the RibbonButton, but unfortunately, I can't find any information about this anywhere. Everyone says that Revit doesn't support this button, which limits its functionality. However, I'm still interested to know if anyone has already solved this problem.


Best regards,

Nikolai Davydov

0 Likes
Reply
Accepted solutions (2)
465 Views
9 Replies
Replies (9)

jeremy_tammik
Autodesk
Autodesk

The Revit API implements its own RibbonButton:

  

  

I would assume that replaces the generic Autodesk.Windows flavour.

  

Jeremy Tammik Developer Advocacy and Support + The Building Coder + Autodesk Developer Network + ADN Open
0 Likes

jeremy_tammik
Autodesk
Autodesk

The Revit API RibbonButton class implements the SetContextualHelp method:

  

  

Here are some samples of using it:

  

    

Jeremy Tammik Developer Advocacy and Support + The Building Coder + Autodesk Developer Network + ADN Open
0 Likes

nikolai_davydovMPWCG
Explorer
Explorer

Hi @jeremy_tammik ,

 

Unfortunately, I can't create it the way you showed because I'm getting the RibbonTab through Autodesk.Windows.

Autodesk.Windows.RibbonTab modifyRibbonTab = Autodesk.Windows.ComponentManager.Ribbon.Tabs.FirstOrDefault(t => t.Id == ModifyTabId);

In your examples, I didn't find anything related to this; it was only about creating a new panel and working with buttons there.

 

Best regards,

Nikolai Davydov

0 Likes

jeremy_tammik
Autodesk
Autodesk

Dear Nikolai,

   

So, you are working in uncharted areas off the official Revit API map. In that case, the Revit API will probably not be of much use to you to address this. Looking forward to hearing how you solve it.

  

Cheers

  

Jeremy

  

Jeremy Tammik Developer Advocacy and Support + The Building Coder + Autodesk Developer Network + ADN Open
0 Likes

bhprest
Advocate
Advocate
Accepted solution

I would love to be proven wrong on this, but I believe that the contextual help that you're looking for only exists as part of the RevitUI object that wraps the Autodesk.Windows.RibbonButton object. I'm fairly certain what you're looking to do is impossible without referencing the RevitUI method. 

 

Luckily, using a little bit of reflection, you can retrieve the RevitUI button even using the AD.Windows modify panel object. Take a look at the source code inside the Revit Lookup addin, here: RibbonUtils.cs 

 

Once you have that, you should be able to call the standard SetContextualHelp method. Hope this helps!

0 Likes

ricaun
Advisor
Advisor
Accepted solution

The easiest way I know to add a RibbonPanel in the modify tab is to move a existent Autodesk.Revit.UI.RibbonPanel to the 'Modify' Autodesk.Windows.RibbonTab.

 

Here is a quick sample:

RibbonPanel ribbonPanel = application.CreatePanel("RibbonPanel");
ribbonPanel.CreatePushButton<Commands.Command>()
    .SetLargeImage("Resources/Revit.ico");

Autodesk.Windows.RibbonPanel awRibbonPanel = ribbonPanel.GetRibbonPanel();
awRibbonPanel.Tab.Panels.Remove(awRibbonPanel);
Autodesk.Windows.RibbonTab awRibbonTab = Autodesk.Windows.ComponentManager.Ribbon.FindTab("Modify");
awRibbonTab.Panels.Add(awRibbonPanel);

 

To get/convert Autodesk.Revit.UI.RibbonPanel to Autodesk.Windows.RibbonPanel use this extension:

 

public static Autodesk.Windows.RibbonPanel GetRibbonPanel(this Autodesk.Revit.UI.RibbonPanel ribbonPanel)
{
    var type = typeof(Autodesk.Revit.UI.RibbonPanel);
    var _ribbonPanel = type.GetField("m_RibbonPanel",
        System.Reflection.BindingFlags.Instance | System.Reflection.BindingFlags.NonPublic)
        ?.GetValue(ribbonPanel) as Autodesk.Windows.RibbonPanel;
    return _ribbonPanel;
}

 

Or you could use my library ricaun.Revit.UI that have this and others extension to help create UI stuff in Revit.

RibbonPanel ribbonPanel = application.CreatePanel("RibbonPanel");
ribbonPanel.CreatePushButton<Commands.Command>()
    .SetLargeImage("Resources/Revit.ico");

ribbonPanel.MoveToRibbonTab("Modify");

 

Be aware that Revit does not expect new panels in the modify tab, if you add to many panels in there weird things could happen in the UI.

 

ricaun_1-1730208638796.png

 

If every single plugin add something in the Modify tab would be a mess, I always make the modify ribbon panel optional so the user can disable.

 

 

 

Luiz Henrique Cassettari

ricaun.com - Revit API Developer

AppLoader EasyConduit WireInConduit ConduitMaterial CircuitName ElectricalUtils

Niko_Davydov
Advocate
Advocate

Hi @ricaun ,

Maybe I don't understand something, but I can't get the F1 help link for these buttons. I also used reflection for panels, but for this panel, I need to place it in the tab. Here is my code, maybe I'm making a simple error.

 

        private void CreateModifyRibbonTab()
        {
            Autodesk.Windows.RibbonTab modifyRibbonTab = Autodesk.Windows.ComponentManager.Ribbon.Tabs.FirstOrDefault(t => t.Id == ModifyTabId);

            ModifyRibbonPanel = _uIApp.CreateRibbonPanel(Assembly.GetCallingAssembly().GetName().Name);

            ButtonConnectorData buttonConnectorData = _modifyButtonData.FirstOrDefault();
            PushButtonData button = buttonConnectorData._pushButtonData;

            ModifyRibbonPanel.AddItem(button);

            modifyRibbonTab.Panels.Add(AppUtils.GetRibbonPanel(ModifyRibbonPanel));
        }

    internal static class AppUtils
    {
        private static readonly FieldInfo RibbonPanelField = typeof(Autodesk.Revit.UI.RibbonPanel).GetField("m_RibbonPanel", BindingFlags.Instance | BindingFlags.NonPublic);

        public static RibbonPanel GetRibbonPanel(this Autodesk.Revit.UI.RibbonPanel panel)
        {
            return RibbonPanelField.GetValue(panel) as RibbonPanel;
        }
    }

 

Best regards,

Nikolai Davydov

0 Likes

ricaun
Advisor
Advisor

In your code just use the SetContextualHelp in the button:

PushButtonData button = ...
button.SetContextualHelp(new ContextualHelp(ContextualHelpType.Url, "https://autodesk.com/"));

 

 

 

Luiz Henrique Cassettari

ricaun.com - Revit API Developer

AppLoader EasyConduit WireInConduit ConduitMaterial CircuitName ElectricalUtils

0 Likes

Niko_Davydov
Advocate
Advocate

It works 🙂 Thanks @ricaun @bhprest @jeremy_tammik ,

i modified the code that was in the RevitLookup fexample, and it finally worked!😊 In my input data, theere was a PushButton, and i changed it to a RibbonButton using Reflection. 
Here's the code showing how it worked

        public static void ModifyPushButton(this RibbonPanel internalPanel, PushButton button)
        {
            Type buttonType = typeof(RibbonItem);
            FieldInfo buttonField = buttonType.GetField("m_RibbonItem", BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.DeclaredOnly);
            var internalButton = (RibbonButton)buttonField.GetValue(button);
            internalPanel.Source.Items.Add(internalButton);
        }
        private void CreateModifyRibbonTab()
        {
            Autodesk.Windows.RibbonTab modifyRibbonTab = Autodesk.Windows.ComponentManager.Ribbon.Tabs.FirstOrDefault(t => t.Id == ModifyTabId);

            ModifyRibbonPanel = new Autodesk.Windows.RibbonPanel()
            {
                IsVisible = false,
                Source = new Autodesk.Windows.RibbonPanelSource() { Title = Assembly.GetCallingAssembly().GetName().Name },
                FloatingOrientation = System.Windows.Controls.Orientation.Vertical,
            };

            ButtonConnectorData buttonConnectorData = _modifyButtonData.FirstOrDefault();

            ModifyRibbonPanel.ModifyPushButton(buttonConnectorData._pushbutton);
            modifyRibbonTab.Panels.Add(ModifyRibbonPanel);
        }

Best regards,

Nikolai Davydov