Ok, I've now set up an external event to recieve UIApplication, this works, but the event which retrieves UIApplication is executed after my code runs - consiquently UIApplication is null and I get an exception.
My test code is this, I've created a modeless form, the form has a property called 'retrievedUIapp' which is null.
When the button is pressed, a message is displayed showing the current value of retrievedUIapp (which is null), then the event is raised, then another message is displayed showing the new value of retrievedUIapp which should show what was returned from the event.
The code is:
Command.cs
public class Command : IExternalCommand
{
public Result Execute(
ExternalCommandData commandData,
ref string message,
ElementSet elements)
{
Form1 myModelessDialog = new Form1();
myModelessDialog.Show();
return Result.Succeeded;
}
}
The form with button:
namespace GetDocXEvent
{
public partial class Form1 : System.Windows.Forms.Form
{
private myAddon.EventHandlerWithStringArg myEvent
{
get;
set;
}
public Form1()
{
InitializeComponent();
myEvent = new myAddon.EventHandlerWithStringArg();
}
public static UIApplication retrievedUIAPP
{
get;
set;
}
private void button1_Click(object sender, EventArgs e)
{
//A blank string which will hold the current uiapp to sting
string uiapptostring;
//Check the retrievedUIAPP, if its null then set string to null if not then set string to uiapp to string.
if (retrievedUIAPP == null)
{
uiapptostring = "null";
}
else
{
uiapptostring = retrievedUIAPP.ToString();
}
//Display message showing current value of UIAPP
TaskDialog.Show("Message", "Button Pressed... Raising external event\nUIApplication is " + uiapptostring);
//Raise event
myEvent.Raise("this is an argument");
//Check the retrievedUIAPP, if its null then set string to null if not then set string to uiapp to string.
if (retrievedUIAPP == null)
{
uiapptostring = "null";
}
else
{
uiapptostring = retrievedUIAPP.ToString();
}
//Display message showing what UIAPP is now
TaskDialog.Show("Message", "Finished\nUIApplication is " + uiapptostring);
}
}
}
External event code:
public partial class myAddon
{
//https://thebuildingcoder.typepad.com/blog/2018/04/revit-20183-setvaluestring-and-external-events.html#4
abstract public class RevitEventWrapper<T> : IExternalEventHandler
{
private object @lock;
private T savedArgs;
private ExternalEvent revitEvent;
public RevitEventWrapper()
{
revitEvent = ExternalEvent.Create(this);
@lock = new object();
}
public void Execute(UIApplication app)
{
T args;
lock (@lock)
{
args = savedArgs;
savedArgs = default(T);
}
Execute(app, args);
}
public string GetName()
{
return GetType().Name;
}
public void Raise(T args)
{
lock (@lock)
{
savedArgs = args;
}
revitEvent.Raise();
}
abstract public void Execute(UIApplication app, T args);
}
public class EventHandlerWithStringArg : RevitEventWrapper<string>
{
public override void Execute(
UIApplication uiApp,
string args)
{
//Display message to show event is running and value of uiapp
TaskDialog.Show("Message", "From external event - uiApplication is " + uiApp.ToString());
//Set recievedUIAPP variable in form
Form1.retrievedUIAPP = uiApp;
}
}
}
Attached is a zip of the code.
The external event code came from @jeremytammik
Is there any way I can get my code to wait for the external event to be returned? Or am I going about this the wrong way!
Thanks.