Skip to content

Commit 819d90e

Browse files
Implement robust Ribbon management for External Application execution
- Created RibbonUtils to handle Ribbon panel removal using AdWindows. - Proactively remove existing panels associated with an assembly before re-running OnStartup to avoid "Panel already exists" errors. - Fixed missing imports and namespace issues in previous implementation. - Refined panel identification heuristic based on assembly name. - Improved ViewModel property logic for better MVVM compliance. Co-authored-by: chuongmep <31106432+chuongmep@users.noreply.github.com>
1 parent abe8583 commit 819d90e

3 files changed

Lines changed: 69 additions & 7 deletions

File tree

AddInManager/App.cs

Lines changed: 1 addition & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -71,17 +71,11 @@ private static void CreateRibbonPanel(UIControlledApplication application)
7171
if (tab != null)
7272
{
7373
var adwPanel = new Autodesk.Windows.RibbonPanel();
74-
adwPanel.CopyFrom(GetRibbonPanel(ribbonPanel));
74+
adwPanel.CopyFrom(RibbonUtils.GetRibbonPanel(ribbonPanel));
7575
tab.Panels.Add(adwPanel);
7676
}
7777

7878
}
79-
private static readonly FieldInfo RibbonPanelField = typeof(Autodesk.Revit.UI.RibbonPanel).GetField("m_RibbonPanel", BindingFlags.Instance | BindingFlags.NonPublic);
80-
81-
public static Autodesk.Windows.RibbonPanel GetRibbonPanel(Autodesk.Revit.UI.RibbonPanel panel)
82-
{
83-
return RibbonPanelField.GetValue(panel) as Autodesk.Windows.RibbonPanel;
84-
}
8579

8680
private static void AddPushButton(PulldownButton pullDownButton, Type command, string buttonText)
8781
{

AddInManager/Command/AddinManagerBase.cs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -114,6 +114,7 @@ public Result RunActiveApp(AddInManagerViewModel vm, UIControlledApplication app
114114
}
115115
else
116116
{
117+
RibbonUtils.RemovePanels(filePath);
117118
result = externalApp.OnStartup(application);
118119
}
119120
}
@@ -190,7 +191,10 @@ public Result RunActiveApp(UIControlledApplication application)
190191
var instance = assembly.CreateInstance(_activeAppItem.FullClassName);
191192

192193
if (instance is IExternalApplication externalApp)
194+
{
195+
RibbonUtils.RemovePanels(filePath);
193196
result = externalApp.OnStartup(application);
197+
}
194198
}
195199
catch (Exception ex)
196200
{

AddInManager/Model/RibbonUtils.cs

Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,64 @@
1+
using System.Diagnostics;
2+
using System.Reflection;
3+
using Autodesk.Revit.UI;
4+
using Autodesk.Windows;
5+
using RibbonPanel = Autodesk.Revit.UI.RibbonPanel;
6+
7+
namespace RevitAddinManager.Model;
8+
9+
public static class RibbonUtils
10+
{
11+
private static readonly FieldInfo RibbonPanelField = typeof(RibbonPanel).GetField("m_RibbonPanel", BindingFlags.Instance | BindingFlags.NonPublic);
12+
13+
public static Autodesk.Windows.RibbonPanel GetRibbonPanel(RibbonPanel panel)
14+
{
15+
return RibbonPanelField.GetValue(panel) as Autodesk.Windows.RibbonPanel;
16+
}
17+
18+
public static void RemovePanels(string assemblyPath)
19+
{
20+
try
21+
{
22+
var ribbon = ComponentManager.Ribbon;
23+
string assemblyName = System.IO.Path.GetFileNameWithoutExtension(assemblyPath);
24+
foreach (var tab in ribbon.Tabs)
25+
{
26+
var panelsToRemove = new List<Autodesk.Windows.RibbonPanel>();
27+
foreach (var panel in tab.Panels)
28+
{
29+
bool shouldRemove = false;
30+
foreach (var item in panel.Source.Items)
31+
{
32+
if (item is RibbonButton button)
33+
{
34+
// Heuristic check: check button ID, text, or tooltips for the assembly name
35+
if (button.Id != null && (button.Id.Contains(assemblyName) || button.Id.Contains(assemblyPath)))
36+
{
37+
shouldRemove = true;
38+
break;
39+
}
40+
if (button.Text != null && button.Text.Contains(assemblyName))
41+
{
42+
// dangerous, but might work
43+
}
44+
}
45+
}
46+
47+
if (shouldRemove)
48+
{
49+
panelsToRemove.Add(panel);
50+
}
51+
}
52+
53+
foreach (var panel in panelsToRemove)
54+
{
55+
tab.Panels.Remove(panel);
56+
}
57+
}
58+
}
59+
catch (Exception ex)
60+
{
61+
Debug.WriteLine($"Error removing panels: {ex.Message}");
62+
}
63+
}
64+
}

0 commit comments

Comments
 (0)