Announcements

The Autodesk Community Forums has a new look. Read more about what's changed on the Community Announcements board.

How do I continue after postcommand?

SimonaQQ
Advocate

How do I continue after postcommand?

SimonaQQ
Advocate
Advocate

Hello,

PostCommand is always executed at the end, similar to "promptforfamilyinstanceplacement". How can I continue other operations after postcommand?
For "promptforfamilyinstanceplacement", I usually catch "operationcanceledexception" to continue execution, but this is not valid for postcommand, such as

uidoc.Application.PostCommand(RevitCommandId.LookupPostableCommandId(PostableCommand.MirrorPickAxis));

So, what should I do?

Thank you very much!! 

0 Likes
Reply
Accepted solutions (2)
2,534 Views
8 Replies
Replies (8)

jeremy_tammik
Autodesk
Autodesk
Accepted solution

You can subscribe to the Idling event:

  

https://www.revitapidocs.com/2022/e233027b-ba8c-0bd1-37b7-93a066efa5a3.htm

  

Your handler will be called after Revit has completed all active commands, e.g., your PostCommand activity.

  

You can specify that Idling be called once only, and you can unsubscribe from it right away after the first call, directly in the event handler.

  

Lots of samples by The Building Coder:

  

https://thebuildingcoder.typepad.com/blog/about-the-author.html#5.28

  

Jeremy Tammik Developer Advocacy and Support + The Building Coder + Autodesk Developer Network + ADN Open

ricaun
Advisor
Advisor
Accepted solution

You could use a custom class like RevitCommandEndedMonitor that uses the idling exactly like @jeremy_tammik suggests.

 

Where I found the reference: https://forums.autodesk.com/t5/revit-api-forum/a-question-about-suppressing-warning-messages-in-revi...

 

Here is my example: https://gist.github.com/ricaun/cc4f0a39b36006883f091bc7f0fc3d35

 

 

using Autodesk.Revit.Attributes;
using Autodesk.Revit.DB;
using Autodesk.Revit.UI;
using Autodesk.Revit.UI.Events;
using System;

namespace RevitAddin
{
    [Transaction(TransactionMode.Manual)]
    public class CommandMoveEnd : IExternalCommand
    {
        public Result Execute(ExternalCommandData commandData, ref string message, ElementSet elementSet)
        {
            UIApplication uiapp = commandData.Application;

            RevitCommandEndedMonitor revitCommandEndedMonitor = new RevitCommandEndedMonitor(uiapp);
            revitCommandEndedMonitor.CommandEnded += OnCommandEnded;

            uiapp.PostCommand(RevitCommandId.LookupPostableCommandId(PostableCommand.Move));

            return Result.Succeeded;
        }

        private void OnCommandEnded(object sender, EventArgs e)
        {
            TaskDialog.Show("Revit", "Move End");
        }
    }

    public class RevitCommandEndedMonitor
    {
        private readonly UIApplication _revitUiApplication;

        private bool _initializingCommandMonitor;

        public event EventHandler CommandEnded;

        public RevitCommandEndedMonitor(UIApplication revituiApplication)
        {
            _revitUiApplication = revituiApplication;

            _initializingCommandMonitor = true;

            _revitUiApplication.Idling += OnRevitUiApplicationIdling;
        }

        private void OnRevitUiApplicationIdling(object sender, IdlingEventArgs idlingEventArgs)
        {
            if (_initializingCommandMonitor)
            {
                _initializingCommandMonitor = false;
                return;
            }

            _revitUiApplication.Idling -= OnRevitUiApplicationIdling;

            OnCommandEnded();
        }

        protected virtual void OnCommandEnded()
        {
            CommandEnded?.Invoke(this, EventArgs.Empty);
        }
    }
}

 

 

See yaa

Luiz Henrique Cassettari

ricaun.com - Revit API Developer

AppLoader EasyConduit WireInConduit ConduitMaterial CircuitName ElectricalUtils

SimonaQQ
Advocate
Advocate
Perfect!
Thank you!!!
Your help is greatly appreciated!
0 Likes

SimonaQQ
Advocate
Advocate
Thank you very much!
0 Likes

adcdao
Advocate
Advocate

Thank you ricaun, it's working very well.

 

Also I used that with PostRequestForElementTypePlacement for placement of family instance. I combined that with this code from Jeremy Tammik (https://thebuildingcoder.typepad.com/blog/2015/02/sending-escape-to-terminate-a-family-instance-plac...) to add only one instance at a time.

 

Thank you again!

André

0 Likes

Chuong.Ho
Advocate
Advocate

It can't resolve the problem when we use Revit Link Command

 

RevitCommandId revitCommandId = RevitCommandId.LookupPostableCommandId(PostableCommand.LinkRevit);
uiApp.PostCommand(revitCommandId);

Dialog will be show and also execute CommandEnded at the same time.

 

Chuong Ho

EESignature

0 Likes

ricaun
Advisor
Advisor

I tested it in Revit 2021 and works normally. The link dialog opens and after closing the OnCommandEnded fires.

 

Technically the RevitCommandEndedMonitor code is triggering in the second Idling event, kinda odd that PostCommand is executing before the Idling event in your case.

 

I was experimenting with using DocumentChanged to get the element that changes/created in the PostCommand, maybe this could be a better approach.

 

Luiz Henrique Cassettari

ricaun.com - Revit API Developer

AppLoader EasyConduit WireInConduit ConduitMaterial CircuitName ElectricalUtils

0 Likes

miguelBW5DE
Contributor
Contributor

Is there a way to know when the user cancel the postable command?

I just came up with this workaround:

			List<Element> regions = new FilteredElementCollector(doc).OfClass(typeof(FilledRegion)).WhereElementIsNotElementType().ToList();
			
			//the user cancelled the command
			if(regionCount == regions.Count){
				return;
			}

 

I'm comparing the number of filled regions existing in the project before and after executing the postable command, but couldn't find a decent way to do this using the IdlingEventArgs.IsCancelled() / Cancellable nor /cancel commands.

 

Best regards,

Miguel G.

 

0 Likes