Collapsed Panel

How exactly does pyRevit create collapsed ribbon panels?

I am trying to recreate my custom pyRevit extension as a standard C# Revit addin, and I realized that collapsed panels are a pyRevit bonus, not in the API. I’m guessing some WPF wizardry.

I tried looking in the pyRevit docs, forums, and code but wasn’t able to find anything.

A great tool to research this can be:

Your question as an input there:

pyRevit creates collapsed ribbon panels by using the Autodesk.Windows (AdWindows) API, which provides access to the underlying WPF ribbon controls that Revit uses internally. This exposes functionality not available through the standard Revit API.

How it Works

1. Metadata Configuration

Panels can be configured to be collapsed through metadata using the collapsed key 1 .

2. UI Creation Process

When creating panels, the UI maker sets the collapse state:

panel_ui.set_collapse(panel.collapsed)
``` [2](#0-1) 

### 3. AdWindows API Usage
The actual collapse is implemented by accessing the AdWindows ribbon panel object and setting its `IsCollapsed` property [3](#0-2) :

```python
def set_collapse(self, state):
    panel_adwnd_obj = self.get_adwindows_object()
    panel_adwnd_obj.IsCollapsed = state

4. Accessing AdWindows Objects

pyRevit gets the AdWindows panel object by iterating through the parent tab’s panels and matching by title 4 .

Implementation for C# Add-in

To replicate this in a C# Revit add-in, you would need to:

  1. Reference AdWindows.dll (Autodesk.Windows namespace)
  2. Get the ribbon control through ComponentManager.Ribbon
  3. Find your panel and set its IsCollapsed property

The key is using Autodesk.Windows.RibbonPanel instead of just Autodesk.Revit.UI.RibbonPanel - the AdWindows version exposes the collapse functionality.

Notes

  • This functionality is not available through the standard Revit API (Autodesk.Revit.UI)
  • pyRevit uses the AdWindows API extensively for advanced UI customization
  • The collapse state is preserved across Revit sessions when set through this method
  • pyRevit also handles RibbonFoldPanel items which automatically fold buttons on resize 5

Wiki pages you might want to explore:

Citations

File: pyrevitlib/pyrevit/extensions/init.py (L123-123)

MDATA_COLLAPSED_KEY = 'collapsed'

File: pyrevitlib/pyrevit/loader/uimaker.py (L589-589)

        panel_ui.set_collapse(panel.collapsed)

File: pyrevitlib/pyrevit/coreutils/ribbon.py (L586-588)

        # RibbonFoldPanel items are not visible. they automatically fold
        # buttons into stack on revit ui resize since RibbonFoldPanel are
        # not visible it does not make sense to create objects for them.

File: pyrevitlib/pyrevit/coreutils/ribbon.py (L1166-1169)

    def get_adwindows_object(self):
        for panel in self.parent_tab.Panels:
            if panel.Source and panel.Source.Title == self.name:
                return panel

File: pyrevitlib/pyrevit/coreutils/ribbon.py (L1215-1217)

    def set_collapse(self, state):
        panel_adwnd_obj = self.get_adwindows_object()
        panel_adwnd_obj.IsCollapsed = state
1 Like

Ok, got it. Here is a barebones method:

// Method to collapse a ribbon panel using Autodesk.Windows, not Autodesk.Revit.UI
public static RibbonPanel CollapseRibbonPanel(string targetPanelName, string targetTabName, bool collapsedState)
{
    // Get the Ribbon Control
    RibbonControl ribbonControl = ComponentManager.Ribbon;

    if (ribbonControl == null) return null;

    // Get the target Ribbon Tab
    RibbonTab targetTab = ribbonControl.FindTab(targetTabName);

    if (targetTab == null) return null;

    // Iterate through the panels
    foreach (RibbonPanel panel in targetTab.Panels)
    {
        // Find the matching panel by name
        if (panel.Source.Title == targetPanelName)
        {
            // Set the collapsed state
            panel.IsCollapsed = collapsedState;

            // Return the matching panel
            return panel; 
        }

    }

    // Panel not found
    return null;
}
1 Like