Reputation: 2633
I have a PushButton in a revit API ribbon and would like to simulate a press on it in order to do some tests (I need a ExternalCommandData object
from the currently active document). However I cannot seem to find anything like a PushButton.Click()
function.
var panel = Application.CreateRibbonPanel("a", "b")
var buttonData = new PushButtonData(name, name, ApplicationInfo.AddInPath, "TestZone.Commands." + "DefaultCommand");
var button = panel.AddItem(buttonData) as PushButton;
With Application being of course the default UIControlledApplication on the OnStartup function. Anyway to know simulate a button click so that I can obtain an ExternalCommandData object of the currently opened document (In the final version there will be checks to ensure that a document is already open ext.) Or is there another way to obtain an externalCommandData?
Note that this question may require you to know the revit API, I doubt that just knowledge of c# will be enough to answer this.
Upvotes: 0
Views: 1593
Reputation: 94
I had many of the same issues with unit testing Revit - and the other users are right, there is no way to get an ExternalCommandData object
without running a command. Fortunately, there's a framework that makes a lot of this possible by automating the startup and running of Revit externally.
https://github.com/DynamoDS/RevitTestFramework
The Dynamo group built this framework to automate their tests, and it offers a lot of great functionality.
Most pertinently for you, it actually exposes a valid ExternalCommandData object
Here is some example code from their framework.
/// <summary>
/// Using the TestModel parameter, you can specify a Revit model
/// to be opened prior to executing the test. The model path specified
/// in this attribute is relative to the working directory.
/// </summary>
[Test]
[TestModel(@"./bricks.rfa")]
public void ModelHasTheCorrectNumberOfBricks()
{
var doc = RevitTestExecutive.CommandData.Application.ActiveUIDocument.Document;
var fec = new FilteredElementCollector(doc);
fec.OfClass(typeof(FamilyInstance));
var bricks = fec.ToElements()
.Cast<FamilyInstance>()
.Where(fi => fi.Symbol.Family.Name == "brick");
Assert.AreEqual(bricks.Count(), 4);
}
RevitTestExecutive.CommandData
offers the ExternalCommandData you are looking for.
Note that there's an issue with installing the RTF as an admin on your machine. I recommend installing it to a local directory as a local user so you don't run into Windows UAC issues.
Upvotes: 1
Reputation: 8339
You cannot simulate the click to launch an external command, and you cannot create a valid ExternalCommandData
object yourself. Only Revit can do that when calling your event handler and providing it with a valid Revit API context in a call-back function, i.e., Revit event handler such as the external command Execute
method.
You can however launch an external command from some other valid Revit API context, just as you can a built-in Revit command, using the PostCommand
API:
http://thebuildingcoder.typepad.com/blog/about-the-author.html#5.3
Upvotes: 0
Reputation: 601
There is no way to obtain an ExternalCommandData object without running a command.
You may be able to use UI Automation to programmatically click on your PushButton. It may be simpler to configure a keyboard shortcut for your command and use UI Automation to simulate the keypresses for you.
See Jeremy Tammik's blog for information on using UI Automation in Revit: http://thebuildingcoder.typepad.com/blog/automation/
Upvotes: 0