ExternalEvent executes after other code inside WPF button click method

ExternalEvent executes after other code inside WPF button click method

revitdeveloper
Contributor Contributor
1,529 Views
8 Replies
Message 1 of 9

ExternalEvent executes after other code inside WPF button click method

revitdeveloper
Contributor
Contributor

To simplify:

I use a WPF GUI wich has a button and a listbox

When the button is clicked i want to execute an ExternalEvent first and after that also update listbox items.

 

Problem:

For some reason the listbox items get updated first, only after that the ExternalEvent is executed.

 

 

This is the relevant part of my code:

 

 

 

 

 

 

private void CreateViewFilters_Click(object sender, RoutedEventArgs e)
{

    // 1st part. Gets executed second
    // Creates new view filters
    CreateViewFilterEvent.Raise();



    // 2nd part. Gets executed first
    // Revit command wich returns a list of all available view filters inside a revit document
    GetExistingViewFiltersCommand getExistingViewFiltersCommand = new GetExistingViewFiltersCommand();
    (Result resultCreateViewFilterCommand, List<string> revitViewFilterList) = getExistingViewFiltersCommand.GetExistingViewFiltersMethod(commandData, ref message, elements);

    // New list that contains all available view filters
    List<string> listBoxValues = new List<string>();

    foreach (string rvf in revitViewFilterList)
    {
        string modifiedRvf = rvf.Replace("_", "__");
        listBoxValues.Add(modifiedRvf);
    }

    // Values from list "listBoxValues" are now updated and will be displayed in the listbox of the wpf gui
    SelectFilters.ItemsSource = listBoxValues;


}

 

 

 

 

 

I have found a forum post wich seems to describe the same problem (not 100% sure)

 

https://forums.autodesk.com/t5/revit-api-forum/when-a-revit-externalevent-is-raised-externalevent-sh...

 

Frankly i have not understood the solution there.

 

 

Could anyone point me in the right direction or offer a solution, or maybe I am completely wrong in my approach?

 

 

 

 

 

 

0 Likes
Accepted solutions (1)
1,530 Views
8 Replies
Replies (8)
Message 2 of 9

jeremy_tammik
Alumni
Alumni

Yes. There is a significant different between raised and executed, just as you hint at in your parenthesis.

  

Just like the Idling event, all Revit external events are executed after Revit has entered an Idling state. In other works, all pending tasks have completed and the queue is clean. Only then, the next item is fetched and executed. 

  

So, depending on how busy Revit is, and what other items are already queued up, it may take while before the external event is executed, with a significant time lag between raise and execute.

  

Your logic needs to take this into account and handle it gracefully.

   

Jeremy Tammik Developer Advocacy and Support + The Building Coder + Autodesk Developer Network + ADN Open
0 Likes
Message 3 of 9

revitdeveloper
Contributor
Contributor

Thank you @jeremy_tammik for your response. I've revised my post to specify "to execute" instead of "to raise."

 

I recognize my issue relates to the item's queue position. That's where I'm stuck.

 

 

When I remove the 2nd part:

 

// 2nd part
// Revit command wich returns a list of all available view filters inside a revit document
GetExistingViewFiltersCommand getExistingViewFiltersCommand = new GetExistingViewFiltersCommand();
(Result resultCreateViewFilterCommand, List<string> revitViewFilterList) = getExistingViewFiltersCommand.GetExistingViewFiltersMethod(commandData, ref message, elements);

// New list that contains all available view filters
List<string> listBoxValues = new List<string>();

foreach (string rvf in revitViewFilterList)
{
    string modifiedRvf = rvf.Replace("_", "__");
    listBoxValues.Add(modifiedRvf);
}

// Values from list "listBoxValues" are now updated and will be displayed in the listbox of the wpf gui
SelectFilters.ItemsSource = listBoxValues;

 

 

Only the 1st part is left:

 

private void CreateViewFilters_Click(object sender, RoutedEventArgs e)
{

    // 1st part
    // Creates new view filters
    CreateViewFilterEvent.Raise();


}

 

 

 

This solution takes effect instantly. One approach could involve triggering separate button-click events for parts 1 and 2.

However, this wouldn't provide an optimal workflow for users. It's preferable for both parts to seamlessly execute with a single button click and in the correct sequence.

 

 

Having explored various options and conducted extensive research, I would greatly appreciate any guidance on how to implement a logic that ensures the execution occurs in the desired order.

 

 

 

 

 

0 Likes
Message 4 of 9

jeremy_tammik
Alumni
Alumni
Accepted solution

You can implement separate external commands for each step of the process and still implement code to execute them sequentially and automatically by stringing them with Idling event calls. Each time after one step completes, you subscribe to an Idling event. Eac h Idling event handler executes the next ste of the chain, and so on.

  

Jeremy Tammik Developer Advocacy and Support + The Building Coder + Autodesk Developer Network + ADN Open
0 Likes
Message 5 of 9

Sean_Page
Collaborator
Collaborator

Obviously not really enough here to make a full comment, but I would highly recommend creating and using Model and View Models if you are going to be doing things like this. That way you can much more easily control refresh / updates in the UI as well as graphically make changes before they are "saved" to the document.

Sean Page, AIA, NCARB, LEED AP
Senionr Partner, Computational Designer, Architect
Message 6 of 9

revitdeveloper
Contributor
Contributor

.

0 Likes
Message 7 of 9

revitdeveloper
Contributor
Contributor

.

0 Likes
Message 8 of 9

revitdeveloper
Contributor
Contributor

.

0 Likes
Message 9 of 9

revitdeveloper
Contributor
Contributor

.

0 Likes