PAUSE for user input

PAUSE for user input

rwebb0418
Contributor Contributor
2,985 Views
6 Replies
Message 1 of 7

PAUSE for user input

rwebb0418
Contributor
Contributor

I am trying to write an addin that will cycle through all of the views (open or not) spell check them and then close all the views with exception of the original view.  Below is the code I've got to date, I can run the spell check on the first view but as soon as it swtiches to the next view it throws an error.

 

Public Function Execute(ByVal cmdData As ExternalCommandData, ByRef msg As String, ByVal elemSet As ElementSet) As Result Implements IExternalCommand.Execute

_cachedCmdData = cmdData

Try
'Dim uiapp As UIApplication = cmdData.Application
''TODO: add your code below.
MsgBox("Running Spell Check on **ALL** Views")
'collect inital view to restore after spell check
Dim actView As Autodesk.Revit.DB.View = CachedUiApp.ActiveUIDocument.ActiveView
Dim actViewID = actView.Id
'collect all views
Dim views As List(Of ElementFilter) = New List(Of ElementFilter)
views.Add(New ElementClassFilter(GetType(View3D)))
views.Add(New ElementClassFilter(GetType(ViewDrafting)))
views.Add(New ElementClassFilter(GetType(ViewPlan)))
views.Add(New ElementClassFilter(GetType(ViewSection)))

Dim filter As LogicalOrFilter = New LogicalOrFilter(views)

Dim col As FilteredElementCollector
col = New FilteredElementCollector(CachedDoc)
col.WhereElementIsNotElementType()
col.WherePasses(filter)

'parse through views and spell check each one
For Each CurView As Autodesk.Revit.DB.View In col
'MsgBox(CurView.ViewName)
If CurView.IsTemplate = False Then
CachedUiApp.ActiveUIDocument.ActiveView = CurView
CachedUiApp.PostCommand(RevitCommandId.LookupCommandId("ID_CHECK_SPELLING"))
'RaiseEvent <test></test> uiapp.Idling = New EventHandler((IdlingEventArgs), (Onidle()))
End If

Next

'restore intial view and close all others
Dim openViews = CachedUiApp.ActiveUIDocument.GetOpenUIViews()
For Each openView As Autodesk.Revit.UI.UIView In openViews
If openView.ViewId <> actViewID Then
openView.Close()
End If
Next
Return Result.Succeeded

Catch ex As Exception

msg = ex.ToString()
Return Result.Failed
End Try
End Function

 

Here's the Error I get:

 

Autodesk.Revit.Exceptions.InvalidOperationException: Revit does not support more than one command are posted.
at Autodesk.Revit.UI.UIApplication.PostCommand(RevitCommandId commandId)
at RevitSpellCheck.SpellCheck.Execute(ExternalCommandData cmdData, String& msg, ElementSet elemSet) in C:\Users\BWebb\Documents\Visual Studio 2010\Projects\RevitSpellCheck\RevitSpellCheck\SpellCheck.vb:line 106

 

Any suggestions are greatly appreciated.

0 Likes
Accepted solutions (1)
2,986 Views
6 Replies
Replies (6)
Message 2 of 7

augusto.goncalves
Alumni
Alumni

The PostCommand help file says: "Posts the command to the Revit message queue to be invoked when control returns from the current API context."


So Revit will not execute the command until it get back the focus... maybe you will need to wait until this command is done but watching Idling event.

Regards,



Augusto Goncalves
Twitter @augustomaia
Autodesk Developer Network
Message 3 of 7

rwebb0418
Contributor
Contributor

Thanks for the suggestion.

 

Now for the Noob follow up:  How?

 

I'm finding events in the Revit API a little confusing.

0 Likes
Message 4 of 7

rwebb0418
Contributor
Contributor

As a followup, I've found and added Event handlers as per instructions found here: http://spiderinnet.typepad.com/blog/2011/07/revit-api-and-vbnet-uiapplication-event-implementation-i...

 

Now however I can't for the life of me figure how I'm to query the handler to watch the idling event.

0 Likes
Message 5 of 7

augusto.goncalves
Alumni
Alumni

Most likely you need a control variable: when you send PostCommand, set the control variable to True. The Idling event trigger all the time, but if the control variable is Trua, then you know a PostCommand was triggered and now it's done, so it's time for a new PostCommand.

 

That a common architecture that works in most scenarios.

Regards,



Augusto Goncalves
Twitter @augustomaia
Autodesk Developer Network
Message 6 of 7

rwebb0418
Contributor
Contributor

I'm stymied, for the life of me I can't figure this out.

 

Public Shared Sub UIAppEvent_Idling_Handler(ByVal sender As Object, ByVal args As EventArgs)

Dim app As Autodesk.Revit.ApplicationServices.Application = TryCast(sender, Autodesk.Revit.ApplicationServices.Application)

Dim uiApp As New UIApplication(app)

Dim specArgs As Autodesk.Revit.UI.Events.IdlingEventArgs = TryCast(args, Autodesk.Revit.UI.Events.IdlingEventArgs)

 

 

I can see the event handler starting however it can't assign sender to the app variable. it keeps returning "nothing" and ends the handler code after Dim uiApp as new UIApplicaiton (app) line

0 Likes
Message 7 of 7

rwebb0418
Contributor
Contributor
Accepted solution

Nevermind I pulled my head out of my **** and figured out the problem.

 

It's not exactly a pretty solution but I've put the code I wanted to run when idle into the Idle handler and then removed the handler after the last run.

 

final solution looks like this:

 

Public Shared Sub UIAppEvent_Idling_Handler(ByVal sender As Object, ByVal args As EventArgs)
Dim openViews
openViews = SpellCheck.CachedUiApp.ActiveUIDocument.GetOpenUIViews()
If openViews.Count = 1 Then
RemoveHandler ExtApp._cachedUiCtrApp.Idling, AddressOf UIAppEvent_Idling_Handler
SpellCheck.CachedUiApp.PostCommand(RevitCommandId.LookupCommandId("ID_CHECK_SPELLING"))
ElseIf openViews.count > 1 Then
SpellCheck.CachedUiApp.PostCommand(RevitCommandId.LookupCommandId("ID_CHECK_SPELLING"))

For Each openView As Autodesk.Revit.UI.UIView In openViews

If openView.ViewId <> SpellCheck.actViewID Then
openView.Close()
Exit For
End If
Next
Else
RemoveHandler ExtApp._cachedUiCtrApp.Idling, AddressOf UIAppEvent_Idling_Handler
End If

End Sub

0 Likes