there is a 4th workaround.
Every time the selection changes, a button has the option to check if it should be enabled via the AvailabilityClassName property. The downside of this mechanisme is, that the button needs to visible. This can easily be accomplished by adding the button to the QuickAccessToolBar.
Define the button in the OnStartup method
public Autodesk.Revit.UI.Result OnStartup(UIControlledApplication application)
{
application.CreateRibbonTab("FAIR");
RibbonPanel m_ribbonPanel = application.CreateRibbonPanel("FAIR", "ModifyPanel");
string thisAssemblyPath = Assembly.GetExecutingAssembly().Location;
PushButtonData buttonData = new PushButtonData("cmd_Dummy",
string.Format("X"), thisAssemblyPath, "FAIR_Space.cmd_Dummy");
buttonData.AvailabilityClassName = "FAIR_Space.CommandEnabler";
m_ribbonPanel.AddItem(buttonData);
application.ControlledApplication.ApplicationInitialized+=ControlledApplication_ApplicationInitialized;
return Result.Succeeded;
}
with the CommandExecute-method and AvailabilityClass
[Autodesk.Revit.Attributes.Transaction(Autodesk.Revit.Attributes.TransactionMode.Manual)]
public class cmd_Dummy : IExternalCommand
{
public Autodesk.Revit.UI.Result Execute(ExternalCommandData revit,
ref string message, ElementSet elements)
{
return Result.Succeeded;
}
}
public class CommandEnabler : IExternalCommandAvailability
{
public bool IsCommandAvailable(UIApplication uiApp, CategorySet catSet)
{
UIDocument uidoc = uiApp.ActiveUIDocument;
if (uidoc == null) return false;
Autodesk.Revit.UI.Selection.Selection sel = uidoc.Selection;
// Raise the SelectionChangedEvent
return false; // disable button
}
}
In the ControlledApplication_ApplicationInitialized-method move the button to the QuickAccessToolBar.
void ControlledApplication_ApplicationInitialized(object sender, Autodesk.Revit.DB.Events.ApplicationInitializedEventArgs e)
{
adWin.RibbonControl ribbon = adWin.ComponentManager.Ribbon;
adWin.RibbonTab FAIRTab = null;
adWin.RibbonPanel MyPanel = null;
adWin.RibbonItem MyButton = null;
// find MyPanel and MyButton
foreach (var tab in ribbon.Tabs)
{
if (tab.Id == "FAIR")
{
FAIRTab = tab;
foreach (var panel in tab.Panels)
{
if (panel.Source.Title == "ModifyPanel")
{
MyPanel = panel;
foreach (var item in panel.Source.Items)
{
if (item.Id == "CustomCtrl_%CustomCtrl_%FAIR%ModifyPanel%cmd_Dummy")
{
MyButton = item;
break;
}
}
}
}
break;
}
}
if (MyPanel != null && MyButton != null && FAIRTab != null )
{
// find a "nice"position for the button
int position = 0;
foreach (var item in adWin.ComponentManager.QuickAccessToolBar.Items)
{
if (string.IsNullOrWhiteSpace(item.Id)) continue;
position++;
if (item.Id == "ID_REVIT_FILE_PRINT") break;
}
// place button on QuickAccessToolBar
if (position < adWin.ComponentManager.QuickAccessToolBar.Items.Count)
{
adWin.ComponentManager.QuickAccessToolBar.InsertStandardItem(position, MyButton);
}
else adWin.ComponentManager.QuickAccessToolBar.AddStandardItem(MyButton);
// remove button from MyPanel and hide tab if no panels
FAIRTab.Panels.Remove(MyPanel);
if (FAIRTab.Panels.Count == 0) FAIRTab.IsVisible = false;
}
}