Determine when Revit API is not available

Determine when Revit API is not available

Anonymous
Not applicable
2,394 Views
12 Replies
Message 1 of 13

Determine when Revit API is not available

Anonymous
Not applicable

I am trying to detect when Revit is in Modify Mode. My plugin's user interface runs in its own thread (since it is running a Dockable web browser, similar to Jeremy's example plugin here).   Currently, if a user clicks a button in our docked panel, then we raise a Revit ExternalEvent, then process it.  That's fine, but if the user is in Edit Mode, then the ExternalEvent never gets executed and it looks to the user like our plugin is just unresponsive.

 

I know Revit disables the ribbon button, but the docked panel is still there and very much interactive.  We'd like to gray out the button in our plugin when user is in Edit Mode.  Second best would be to at least detect that we have no access to the Revit API due to Edit Mode and notify the user.  Is there a way to detect this mode? The API is unresponsive in edit mode, so is there an event generated before Modify mode is entered?

 

A similar question was asked previously, however there never was a solution: https://forums.autodesk.com/t5/revit-api-forum/detecting-modify-mode-aka-edit-mode/td-p/5616006 .

0 Likes
2,395 Views
12 Replies
Replies (12)
Message 2 of 13

jeremytammik
Autodesk
Autodesk

Very interesting question.

 

Glad to hear you have your system up and running reliably.

 

Yes, this is tricky.

 

You can only call the Revit API when you have a valid API context, so the API cannot provide a function for checking that can be called when you are not in a valid context.

 

The only workaround I can think of is to implement another external event  with a separate thread and a Windows timer driving it, so it is not raised all too often, and use that as a notification signal to notify when the API is accessible and when it is not due to UI business.

 

I hope this helps.

 

Cheers,

 

Jeremy



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

Message 3 of 13

Anonymous
Not applicable

Thanks Jeremy,

 

This is unfortunate. It would be nice if Revit IExtenralEvent.Raise method had another variant like:

 

bool IExternalEvent.RaiseImmediate();

 

which would return true if it was able to raise the event and false otherwise. That way plugins can make accurate and immediate decisions as to what information to present to the user.

 

Perhaps a suggestion for future API version..

0 Likes
Message 4 of 13

jeremytammik
Autodesk
Autodesk

Absolute, I totally agree. 

 

Please raise an API wish for that in the Revit Idea Station and gather lots of votes for it.

 

Thank you!

 

Cheers,

 

Jeremy



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

0 Likes
Message 5 of 13

Anonymous
Not applicable

Ok, I've added an API wish for what @Anonymous described here.

0 Likes
Message 6 of 13

Anonymous
Not applicable

There is a way to determine if you are in correct context and that is to start a new transaction and if it throws InvalidOperationException with a message saying something like "not allowed to start transaction outside correct context" then you are not in a correct context 😃

Do note that you need to catch the Autodesk.Revit.Exceptions.InvalidOperationException (there is another one in System)

This has worked for me, have not yet seen any wierd crashes because of this. 

 

This snipped of code (took it right out of my class so there might be some objects that need declaration):

 

        public bool IsValidContext()
        {
            if (Document == null) return false;

            if (Document.IsModifiable) return true;

            var trTemp = new Transaction(Document, "Temp");
            try
            {
                trTemp.Start();
                trTemp.RollBack();
                return true;
            }
            catch (Autodesk.Revit.Exceptions.InvalidOperationException ex)
            {

                return false;
                
            }


        }

 

Edit: Ups I missunderstood the question and I could not find a way to remove my response… 

0 Likes
Message 7 of 13

Anonymous
Not applicable

@Anonymous,no problem, and thanks for trying to help out! 

 

That's good to know how to check if you're in the current context, I'll keep that in mind.  You already noted that you misunderstand, but to be more explicit for other readers, we're looking for how to see if Revit will hand over control of its single thread if you raise a Revit event (before the Revit event is raised).

0 Likes
Message 8 of 13

jeremytammik
Autodesk
Autodesk

The most recent information I have on this is from the questions at the Revit API panel discussion at AU two weeks ago:

 

https://thebuildingcoder.typepad.com/blog/2018/11/dashboard-regen-and-revit-api-panel-at-au.html#2.4

 

  • How do you know when Revit is in a state where it will respond to an event?
    • You can’t definitively know. It’s why it has to be an asynchronous mechanism.

 

Cheers,

 

Jeremy

 



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

0 Likes
Message 9 of 13

Anonymous
Not applicable

Yes, sorry about that. 
Two things come to mind in that case: 

1. Use the AdWindows dll to access the "inner workings" of the UI and check if the buttons are enabled. This should, if you tune it correctly, (look at the right buttons etc), give you an idea if the user is in a edit mode, or the ui is disabled because of eny other reason.  

2. Test for avaliability: create an external event whos sole responsibility is to be raised and return a message to the UI if it was indeed executed. 

 

 

0 Likes
Message 10 of 13

Wolfgang.B.Weh
Enthusiast
Enthusiast

Here is how I detect edit mode:

https://forums.autodesk.com/t5/revit-api-forum/detecting-modify-mode-aka-edit-mode/m-p/10060028/high...

 

Hope this helps.

 

Regards

 

Wolfgang

0 Likes
Message 11 of 13

zhuliyi0
Enthusiast
Enthusiast

I tried the first option, it works under most circumstances, but not all, but at least that's enough for what I want to monitor.  

 

The .IsEnabled property is always true, so I didn't use it. Instead I had to look for any one of several "signature panels" among all panels inside Autodesk.Windows.ComponentManager.Ribbon. If any one of these panels exist, or visible, Revit is inside some kind of editing mode. These panels are (panel ids):

 

"editgroup" (plus a random GUID string)

"editassembly"

"sketch_finish_cancel_shr"

"workplane_shr"

"Dialog_HostObj_SlabShapeMainEditorBar"

"inplace_mode_shr" (this one always exists, but only visible when in edit mode)

 

I might missed some other panels, will find out. For now, it works for me.

 

If .IsEnabled property works as it should, then I can simply check "external tool" button's availability, and not worry about catch all circumstances of edit mode with panels. Unfortunately, that didn't work.

Message 12 of 13

jeremy_tammik
Alumni
Alumni

Thank you for sharing this new approach.

 

This other discussion seems related and may provide some additional useful ideas:

  

https://forums.autodesk.com/t5/revit-api-forum/detecting-modify-mode-aka-edit-mode/td-p/5616006

  

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

RPTHOMAS108
Mentor
Mentor

Reading through this thread and the other one it is worth noting two things for future record:

1) When you raise an external event you get a response, I assume that response will be 'Rejected' if Revit is busy. If you only care about informing the user after they press the button you can probably do it by reviewing the result.

2) Revit is available when it is idle, the various edit modes are not the only thing that puts it in this non-idle state. So if the aim is to change the modeless control to visually indicate it can't be used then you need a more generic approach.

 

What I wrote on other thread relies on idling event. In theory you could adapt it to not use SetRaiseWithoutDelay, it would be a bit more complicated however. The issue was always that whilst you can detect an exit from edit mode (with default idling event behaviour) you could not detect an entrance into edit mode.

0 Likes