Is it possible to obtain objects from event handlers using ref?

Is it possible to obtain objects from event handlers using ref?

Anonymous
Not applicable
1,908 Views
5 Replies
Message 1 of 6

Is it possible to obtain objects from event handlers using ref?

Anonymous
Not applicable

Hello everyone!

 

As the title says, is it possible to obtain objects from event handlers using ref?

 

I want to use Revit API and WPF in order to extract a list of elements from the model (and for this I'm going to use Revit API) and then import it to WPF. However, as I use external event in order to use Revit API, all the lists and instances that are obtained in the event are not transferred to the main code (i.e. Window and Button_Click).

 

 

So this is the summary of the code I'm using:

//So I'm doing a Window in WPF
public partial class Window1: Window
    {

    //create the External Events which will be read from the previous window
    public ExternalEvent Event;
//create an instance that should be readable throughout the code and that should have the same reference that the one in the EvenHander (list)
    IList<string> list;


    public ThirdWindow(ExternalEvent exEvent)
    {
        InitializeComponent();
        Event = exEvent;
    }


//button in WPF that will raise the event and use the list
    private void button_Click(object sender, RoutedEventArgs e)
    {

        //call the event
        Event.Raise();
    //and then I want to store in List_button the list I had in the EventHandler
        ref IList<string> List_button = ref list;

    }


public class EventRegisterHandler_IdentifyMaterialsWithoutSP : IExternalEventHandler
    {

        public bool EventRegistered { get; set; }
        public IList<string> MaterialList_W3 { get; set; }

        public void Execute(UIApplication app)
        {
            UIDocument uiDoc = app.ActiveUIDocument;
            Document doc = app.ActiveUIDocument.Document;

    //in this part I'm calling Class1 in order to use Function1
            Class1 revitFunction = new Class1();
    //Function1 will allow me to store a IList of stuff
            IList<string> List1 = revitFunction.Function1(doc);

    //and I want to be able to have access to this list OUTSIDE the event handler
            ref IList<string> list = ref List1; 
        }

        public string GetName()
        {
            return "EventRegisterHandler";
        }
    }

So, is there a way to extract information out of the event handler? is it possible to extract a IList<> from the event handler and use it in the Window Class?

Accepted solutions (1)
1,909 Views
5 Replies
Replies (5)
Message 2 of 6

jeremytammik
Autodesk
Autodesk

You can only make use of the Revit API methods within a valid Revit API context, i.e., within the event handler.

 

Therefore, you need to access, read and store all the required information inside that scope.

 

After that, you can do anything you like, except making use of the Revit API, e.g., you cannot query Revit for any further data.

 

Cheers,

 

jeremy



Jeremy Tammik
Developer Technical Services
Autodesk Developer Network, ADN Open
The Building Coder

Message 3 of 6

Anonymous
Not applicable

Thank you jeremy!

 

Do you think it is possible to extract information out of the event? 

 

In this case I just want to run Revit API functions within the event.

 

But then I also stored in a List (IList<string> list = List1;) the information that I want outside the event, which is basically a list of strings that represent the name of elements in the project. 

 

Is there no way to have access to this information outside the handler? Or copy that list to a list outside the handler during the event?

 

Sorry if I'm asking stupid/obvious questions.

 

Cheers

 

0 Likes
Message 4 of 6

jeremytammik
Autodesk
Autodesk
Accepted solution

Sure.

 

You can store the strings in a ref List.

 

Or a static class variable.

 

These are .NET basics.

 

Please read about, e.g., '.net passing data between classes':

 

https://duckduckgo.com/?q=.net+passing+data+between+classes

 

Cheers,

 

Jeremy



Jeremy Tammik
Developer Technical Services
Autodesk Developer Network, ADN Open
The Building Coder

Message 5 of 6

Anonymous
Not applicable

jeremy,

 

You've literally saved my ***!

 

I'm not a great C# programmer nor do have a computer background, but I'll just share the solution that worked out for me so others can follow the same steps and adapt to their needs.

 

Basically, I just added a class that will store "global parameters" using the 'static' modifier (https://docs.microsoft.com/en-us/dotnet/csharp/programming-guide/classes-and-structs/static-classes-...)

 

namespace NamespaceOfYourCode
{
    public class GlobalObjects
    {
        public static string x;
        public static List<string> xList;
        //other global objects you want
    }

//...

public ThirdWindow(ExternalEvent exEvent)
    {
        InitializeComponent();
        Event = exEvent;
        //raise the event as soon as you open the window
        Event.Raise();
    }

//...

public class EventRegisterHandler_IdentifyMaterialsWithoutSP : IExternalEventHandler
    {

        public bool EventRegistered { get; set; }
        public IList<string> MaterialList_W3 { get; set; }

        public void Execute(UIApplication app)
        {
            UIDocument uiDoc = app.ActiveUIDocument;
            Document doc = app.ActiveUIDocument.Document;

    //in this part I'm calling Class1 in order to use Function1
            Class1 revitFunction = new Class1();
    //Function1 will allow me to store a IList of stuff
            IList<string> List1 = revitFunction.Function1(doc);

    //and I want to be able to have access to this list OUTSIDE the event handler
            GlobalObjects.xList=List1; 
        }

        public string GetName()
        {
            return "EventRegisterHandler";
        }
    }

It is important that the event is raised as soon as the window shows up. As far as I know, when you click a button, and then raise a Revit event, it will only "finish" it when the button event is closed. So, if you only raise the event in the button, the List will be null and only after the button closes the List will have its values. So, raise the event in the main window and then when you need it in the button the List will already have the stuff you want.

 

Is this the best solution? I hardly think so, but it's working for me.

 

Only thanks to you jeremy!

 

Cheers

Message 6 of 6

halukuzuner
Advocate
Advocate

Hi Rubens1234,

Your code worked for me except you said:

"As far as I know, when you click a button, and then raise a Revit event, it will only "finish" it when the button event is closed."

 

How to close button event

0 Likes