-
Notifications
You must be signed in to change notification settings - Fork 47
/
Copy pathApp.cs
185 lines (159 loc) · 6.86 KB
/
App.cs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using System.Threading;
using System.Windows.Media.Imaging;
using System.Windows.Threading;
using Autodesk.Revit.UI;
using Autodesk.Revit.UI.Events;
namespace RevitTemplate
{
/// <summary>
/// This is the main class which defines the Application, and inherits from Revit's
/// IExternalApplication class.
/// </summary>
class App : IExternalApplication
{
// class instance
public static App ThisApp;
// ModelessForm instance
private Ui _mMyForm;
// Separate thread to run Ui on
private Thread _uiThread;
public Result OnStartup(UIControlledApplication a)
{
_mMyForm = null; // no dialog needed yet; the command will bring it
ThisApp = this; // static access to this application instance
// Method to add Tab and Panel
RibbonPanel panel = RibbonPanel(a);
string thisAssemblyPath = Assembly.GetExecutingAssembly().Location;
// BUTTON FOR THE SINGLE-THREADED WPF OPTION
if (panel.AddItem(
new PushButtonData("WPF Template", "WPF Template", thisAssemblyPath,
"RevitTemplate.EntryCommand")) is PushButton button)
{
// defines the tooltip displayed when the button is hovered over in Revit's ribbon
button.ToolTip = "Visual interface for debugging applications.";
// defines the icon for the button in Revit's ribbon - note the string formatting
Uri uriImage = new Uri("pack://application:,,,/RevitTemplate;component/Resources/code-small.png");
BitmapImage largeImage = new BitmapImage(uriImage);
button.LargeImage = largeImage;
}
// BUTTON FOR THE MULTI-THREADED WPF OPTION
if (panel.AddItem(
new PushButtonData("WPF Template\nMulti-Thread", "WPF Template\nMulti-Thread", thisAssemblyPath,
"RevitTemplate.EntryCommandSeparateThread")) is PushButton button2)
{
button2.ToolTip = "Visual interface for debugging applications.";
Uri uriImage = new Uri("pack://application:,,,/RevitTemplate;component/Resources/code-small.png");
BitmapImage largeImage = new BitmapImage(uriImage);
button2.LargeImage = largeImage;
}
// listeners/watchers for external events (if you choose to use them)
a.ApplicationClosing += a_ApplicationClosing; //Set Application to Idling
a.Idling += a_Idling;
return Result.Succeeded;
}
/// <summary>
/// What to do when the application is shut down.
/// </summary>
public Result OnShutdown(UIControlledApplication a)
{
return Result.Succeeded;
}
/// <summary>
/// This is the method which launches the WPF window, and injects any methods that are
/// wrapped by ExternalEventHandlers. This can be done in a number of different ways, and
/// implementation will differ based on how the WPF is set up.
/// </summary>
/// <param name="uiapp">The Revit UIApplication within the add-in will operate.</param>
public void ShowForm(UIApplication uiapp)
{
// If we do not have a dialog yet, create and show it
if (_mMyForm != null && _mMyForm == null) return;
//EXTERNAL EVENTS WITH ARGUMENTS
EventHandlerWithStringArg evStr = new EventHandlerWithStringArg();
EventHandlerWithWpfArg evWpf = new EventHandlerWithWpfArg();
// The dialog becomes the owner responsible for disposing the objects given to it.
_mMyForm = new Ui(uiapp, evStr, evWpf);
_mMyForm.Show();
}
/// <summary>
/// This is the method which launches the WPF window in a separate thread, and injects any methods that are
/// wrapped by ExternalEventHandlers. This can be done in a number of different ways, and
/// implementation will differ based on how the WPF is set up.
/// </summary>
/// <param name="uiapp">The Revit UIApplication within the add-in will operate.</param>
public void ShowFormSeparateThread(UIApplication uiapp)
{
// If we do not have a thread started or has been terminated start a new one
if (!(_uiThread is null) && _uiThread.IsAlive) return;
//EXTERNAL EVENTS WITH ARGUMENTS
EventHandlerWithStringArg evStr = new EventHandlerWithStringArg();
EventHandlerWithWpfArg evWpf = new EventHandlerWithWpfArg();
_uiThread = new Thread(() =>
{
SynchronizationContext.SetSynchronizationContext(
new DispatcherSynchronizationContext(
Dispatcher.CurrentDispatcher));
// The dialog becomes the owner responsible for disposing the objects given to it.
_mMyForm = new Ui(uiapp, evStr, evWpf);
_mMyForm.Closed += (s, e) => Dispatcher.CurrentDispatcher.InvokeShutdown();
_mMyForm.Show();
Dispatcher.Run();
});
_uiThread.SetApartmentState(ApartmentState.STA);
_uiThread.IsBackground = true;
_uiThread.Start();
}
#region Idling & Closing
/// <summary>
/// What to do when the application is idling. (Ideally nothing)
/// </summary>
void a_Idling(object sender, IdlingEventArgs e)
{
}
/// <summary>
/// What to do when the application is closing.)
/// </summary>
void a_ApplicationClosing(object sender, ApplicationClosingEventArgs e)
{
}
#endregion
#region Ribbon Panel
public RibbonPanel RibbonPanel(UIControlledApplication a)
{
string tab = "Template"; // Tab name
// Empty ribbon panel
RibbonPanel ribbonPanel = null;
// Try to create ribbon tab.
try
{
a.CreateRibbonTab(tab);
}
catch (Exception ex)
{
Util.HandleError(ex);
}
// Try to create ribbon panel.
try
{
RibbonPanel panel = a.CreateRibbonPanel(tab, "Develop");
}
catch (Exception ex)
{
Util.HandleError(ex);
}
// Search existing tab for your panel.
List<RibbonPanel> panels = a.GetRibbonPanels(tab);
foreach (RibbonPanel p in panels.Where(p => p.Name == "Develop"))
{
ribbonPanel = p;
}
//return panel
return ribbonPanel;
}
#endregion
}
}