Here is a quick little question on dynamically toggling the display of a custom ribbon panel, e.g. depending on the currently activated Revit disciplines.
First, however, let me share this nice and wise little quote regarding the current weather situation and actually life and happiness in general from the German humourist Karl Valentin (1882-1948):
I am happy if it rains – because if I am unhappy, it still goes on raining
(Ich freue mich, wenn es regnet – denn wenn ich mich nicht freue, regnet es auch).
Toggle Ribbon Panel Visibility
Question: Is there an easy way to dynamically turn a specific user ribbon panel on or off depending on the currently active Revit disciplines?
For instance, I have implemented these two separate Structure and MEP ribbon panels within our company's ribbon tab, and I would like them to automatically reflect the changes in discipline option.
When the structural and systems disciplines are disabled in the Revit user interface, these two panels should disappear:
I am aware of the dedicated VisibilityMode tag defined by the add-in manifest XML format, but that only enables and disables individual buttons depending on the discipline.
The command availability class provides even greater control and also only affects individual buttons.
I already made use of both these two options for other purposes.
The Revit 2013 API provides new properties like Application.IsStructureEnabled, etc. I would like the information returned by that property to dynamically turn the entire corresponding ribbon panel on and off, not just a single command.
Answer: Yes, the Revit API actually does provide complete and simple support for this functionality, as you can discover by exploring the methods and properties provided by the respective classes. The Revit API documentation always has some new little surprise to offer, if you study it carefully.
In this case, you can make use of the read-write RibbonPanel.Visible property, which can be set to false to hide a panel.
You can save the RibbonPanel instance in a global variable in your application class to switch its state at will.
You can also make use of a self-implemented toggle button in one panel to control another panel's visibility.
Hi Jeremy,
Great article, thanks...
How do you think we could dynamically hide the ribbon panel based on the type of Revit file that is opened (family, project) ? For instance if you want to show it only when a family document is active, and without any toggle button.
Even with a Ribbon panel global instance in the "App" class, I don't see where to make it visible/unvisible without a toggle button to control it. In the "Command" class ? With an updater ?
Thanks.
Posted by: m.vallee | August 19, 2013 at 11:34
Dear Maxime,
Thank you for your appreciation! Glad you like it.
As mentioned above, you can activate and deactivate individual buttons using command availability classes.
In those classes you can implement any kind of checking functionality you desire, e.g. using the type of Revit document opened, the time of day, or any other trigger.
Maybe you can call the RibbonPanel.Visible property from withing a command availability class?
Please do let us know how you fare with this! Thank you!
Cheers, Jeremy.
Posted by: Jeremy Tammik | August 21, 2013 at 07:48
Hi Jeremy,
I tried what you said, creating this command availability class :
class FamilyOnlyAvailability : IExternalCommandAvailability
{
public bool IsCommandAvailable(UIApplication applicationData, CategorySet selectedCategories)
{
// we want to display the rp when a family doc is active
bool result = (null != applicationData.ActiveUIDocument) && applicationData.ActiveUIDocument.Document.IsFamilyDocument;
// hide or display the ribbonpanel
List liste_rp = applicationData.GetRibbonPanels();
foreach (RibbonPanel rp in liste_rp)
{
if (rp.Name == Util.Caption)
{
if (!result)
rp.Visible = false;
else rp.Visible = true;
break;
}
}
return result;
}
}
The problem is once the Ribbon panel has been hidden, the command availability class is no more used... so it can't be displayed again... :(
Posted by: m.vallee | August 22, 2013 at 10:48
Dear Maxime,
Thank you for this very cool partial result.
Ok, so you can hide it successfully.
Now you can try to implement something to display it again, e.g. using a separate command button in a separate main control panel of your application.
This sounds pretty useful to me, provided your application is large and complex enough to warrant multiple panels, some of which you wish to sometimes hide.
Cheers, Jeremy.
Posted by: Jeremy Tammik | August 22, 2013 at 12:33
Hi Jeremy.
That would be a good trick, but this is not what I want to do. My idea was to completely hide the ribbon panel except when there is a family document active, because it is the only case where the commands in the rp can be used. I don't want to add a button to control visibility because we now have plenty of ribbon panels and commands in the add-in tab, so lighten it becomes quite necessary...
I think it would be nice if there was a IRibbonPanelAvailability class to implement, which would be the equivalent of IExternalCommandAvailability but for panels.
Cheers.
Maxime
Posted by: m.vallee | August 23, 2013 at 03:43
Dear Maxime,
Thank you for your research and clear analysis.
I submitted the wish list item CF-6 [API wish: ribbon panel availability class] for you for the requested functionality.
Cheers, Jeremy.
Posted by: Jeremy Tammik | August 23, 2013 at 05:25
Dear Jeremy,
Thanks a lot for your help and for submitting the request.
Cheers.
Maxime
Posted by: m.vallee | August 23, 2013 at 08:19