Prompt User to Avoid Modeless Interaction

Once again on the topic of asynchronous interaction with Revit, which is not supported by the Revit API, and often worked around using the Idling and external events...

As I recently pointed out, no Revit API methods at all can be called outside a valid Revit API context, not even the new DoDragDrop method or Application.IsQuiescent property.

I already presented two convincing examples in the past of how you could work around a lack of direct API access by interacting intelligently with the user instead:

In the first, lack of certain API functionality was worked around by prompting the user to execute an action instead.

In the second, an action was detected that could not be undone programmatically, but a warning can easily be displayed allowing the user to undo if she so desires.

Here is an example by Paul Vella of Autodesk Consulting in Melbourne, Australia, of how you can easily and safely avoid a potentially complex and risky modeless interaction by providing an adequate user interface instead:

Question: I have a command that identifies a list of elements from the Revit model, and displays them in a modeless dialog to the user. The dialog is modeless so that the user can interact with the model, but I also want the user to be able to change the current selection (and zoom to that item) by selecting items from my dialog.

The zoom to part works, and the selection appears to change, but the properties panel does not update correctly.

Apparently the issue is that the Revit command has ended once the dialog has been displayed, and therefore my selection code runs outside of a command and lacks a valid Revit API context.

Is it possible to programmatically create a command context or otherwise to get my selection code to work, and have the properties panel update correctly?

One idea I had was to have a separate command button to do the selection, and call this programmatically from my form. But I could not work out how to programmatically click a PushButton on the ribbon.

Answer: Nope, I am sorry to say it is not possible to create a command context in the way you describe, nor does the Revit API provide any way to programmatically simulate a ribbon push button click.

The only way I know to safely achieve what you are aiming for is to make use of the Idling event or the new external event framework.

Response: The solution I went with was to create a new button on the ribbon entitled 'Zoom to Sync Error'. When clicked, this button determines the currently selected item in the modeless form, which is accessible through a singleton instance.