Resume original command with CreateAddInCommandBinding

Resume original command with CreateAddInCommandBinding

sean_dodsworth
Contributor Contributor
1,600 Views
12 Replies
Message 1 of 13

Resume original command with CreateAddInCommandBinding

sean_dodsworth
Contributor
Contributor

If I use CreateAddInCommandBinding to intercept a command is there any way to resume the command in the Executed event handler?

For example something like this:

var cmd = RevitCommandId.LookupCommandId("ID_FILE_SAVE_TO_MASTER");
var binding = app.CreateAddInCommandBinding(cmd);
binding.Executed += Binding_Executed;
private static void Binding_Executed(object sender, ExecutedEventArgs e) { // Run my code here
// Resume original command }

I know in this example I could programmatically do a sync but I want to display the sync dialog to the user as normal

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

jeremytammik
Autodesk
Autodesk

I do not believe this is possible.

 

For safety's sake, I am checking with the development team for you.

 

Best regards,

 

Jeremy

 



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

0 Likes
Message 3 of 13

sean_dodsworth
Contributor
Contributor

OK thanks Jeremy

0 Likes
Message 4 of 13

Revitalizer
Advisor
Advisor

Hi,

 

didn't test it, but there is a method

 

UIControlledApplication.RemoveAddinCommandBinding(RevitCommandId)

 

 

Revitalizer




Rudolf Honke
Software Developer
Mensch und Maschine





0 Likes
Message 5 of 13

Revitalizer
Advisor
Advisor

Hi again,

 

In the Binding_Executed, you could

 

  • run your code
  • remove the command binding
  • invoke the (original) command again: UIApplication.PostCommand(cmd)

 

You would need to create a new command binding after the original command has been executed, perhaps triggered in the Idling event...?


Revitalizer




Rudolf Honke
Software Developer
Mensch und Maschine





Message 6 of 13

sean_dodsworth
Contributor
Contributor

Thats an interesting idea. I tried it and was able to remove the binding and invoke the original command but havent been able to successfully recreate the command binding afterwards. 

When I do it in a ViewActivated event it does the CreateAddInCommandBinding step without raising an exception but the event handler is never called. Maybe i will try the Idling event.

0 Likes
Message 7 of 13

jeremytammik
Autodesk
Autodesk

I heard back from the development team on this with some pretty helpful news:

 

Note that there is no way to conditionally run the original command after you have defined you own in its place. That's why the Revit API also provides the BeforeExecuted callback in AddInCommandBinding.  If you override just that one, it will run your code first and then the standard command.

 



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

Message 8 of 13

sean_dodsworth
Contributor
Contributor

That works well except it wont let start a transaction within that BeforeExecuted handler, i get this error:

Cannot modify the document for either a read-only external command is being executed, or changes to the document are temporarily disabled.
0 Likes
Message 9 of 13

jeremytammik
Autodesk
Autodesk

Yes. If you need a new transaction, then creating your own sequence of steps making use of the Idling event is probably the best way to go.

 



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

0 Likes
Message 10 of 13

Sean_Page
Collaborator
Collaborator

It is very much possible...

 

1. Add the Binding

2. 

private Result AddCommandBindings(UIControlledApplication application, string name)
        {
            RevitCommandId rCommandId = RevitCommandId.LookupCommandId(name);
            if (rCommandId.CanHaveBinding)
            {
                try
                {
                    if (name == "ID_INPLACE_COMPONENT")
                    {
application.CreateAddInCommandBinding(rCommandId).Executed += new EventHandler<ExecutedEventArgs>(this.DisableCommand);
                    }
                }
                catch
                {
                    MessageBox.Show("Command " + name + " is already bound.");
                }
            }
            return Result.Succeeded;
        }

        private void DisableCommand(object sender, ExecutedEventArgs args)
        {
            using (Forms.RevitPostCommandForm rpc = new Forms.RevitPostCommandForm(args.CommandId))
            {
                if (rpc.ShowDialog() == DialogResult.OK)
                {
                    ControlID.postCommand = args.CommandId.Name;
                    UIDocument uiDoc = new UIDocument(args.ActiveDocument);
                    uiDoc.Application.RemoveAddInCommandBinding(args.CommandId);
                    ControlID.application.Idling += new EventHandler<IdlingEventArgs>(PostCommand_Idling);
                    idleCheck = false;
                    uiDoc.Application.PostCommand(args.CommandId);
                }
            }
        }
private void PostCommand_Idling(object sender, IdlingEventArgs args)
        {
            if (idleCheck)
            {
                AddCommandBindings(ControlID.application, ControlID.postCommand);
                ControlID.application.Idling -= PostCommand_Idling;
            }
            else
            {
                idleCheck = true;
            }
        }

 

 

Sean Page, AIA, NCARB, LEED AP
Partner, Computational Designer, Architect
Message 11 of 13

matthew_taylor
Advisor
Advisor

Cheers @Sean_Page. I'm working on something similar and your solution works a treat.

 

Are there any edge cases that I should be on the lookout for (to triage)?


Cheers,

-Matt
_______________________________________________________________________________
Marking a post as a 'solution' helps the community. Giving a post 'Kudos' is as good as saying thanks. Why not do both?
0 Likes
Message 12 of 13

Sean_Page
Collaborator
Collaborator

Matt,

Not that I recall running into. I use this for a variety of things and it does work well.

Sean Page, AIA, NCARB, LEED AP
Partner, Computational Designer, Architect
Message 13 of 13

matthew_taylor
Advisor
Advisor

Thank you kindly for your quick response!


Cheers,

-Matt
_______________________________________________________________________________
Marking a post as a 'solution' helps the community. Giving a post 'Kudos' is as good as saying thanks. Why not do both?
0 Likes