Revit API Forum
Welcome to Autodesk’s Revit API Forums. Share your knowledge, ask questions, and explore popular Revit API topics.
cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 

Pick Objects - Not able to draw bounding box

4 REPLIES 4
SOLVED
Reply
Message 1 of 5
retug_austin
244 Views, 4 Replies

Pick Objects - Not able to draw bounding box

Beginner to the revit api, I am trying to prompt my user to select objects with a selection box in revit.

 

I am using this line of code:

        public void GatherRevitBeams(object sender, RoutedEventArgs e, Document doc, UIDocument uidoc, ref List<CustomLine> RevitBeams)
        {

            //we will pass in doc and uidoc becuase these are already being accessed in the mainwindow xaml code
            IList<Reference> pickedObjs = uidoc.Selection.PickObjects(ObjectType.Element, "Select Elements");

 

I have this GatherRevitBeams function in a separate C sharp class (RevitInfo) from that of my MainWindow.xaml.cs file and I think this might be part of my trouble. Pressing the GatherRevitBeams button will fire, switching the screen over to the selection mode, but I am unable to draw a window to select or do anything. Clicking on the screen yields a "windows beep" noise and I am unable to progress in my code.

 

austinguter_1-1703610155662.png

 

 

Any ideas where I am going wrong? I think I may need to start up the IExternal Command as shown in this video, but I am bit unclear on how to do this in a c sharp class that is separated from the MainWindow.xaml.cs file.

 

austinguter_0-1703610002091.png

 

Full code on github if you want to take a look.

austinguter_2-1703610273334.png

Appreciate you help!

4 REPLIES 4
Message 2 of 5
retug_austin
in reply to: retug_austin

I have played a little bit with this, but still not working. Seems like I need to start up a new class with that inherits from IExternalCommand,

namespace rebarBenderMulti
{
    [Transaction(TransactionMode.Manual)]
    public class YourCommandName : IExternalCommand, IExternalEventHandler
    {
        private ExternalEvent externalEvent;
        // Add a property to store the count of pickedObjs
        public int PickedObjectsCount { get; private set; }

        public Result Execute(
            ExternalCommandData commandData,
            ref string message,
            ElementSet elements
            )
        {
            // Retrieve the active UIDocument and Document
            UIDocument uidoc = commandData.Application.ActiveUIDocument;
            Document doc = uidoc.Document;

            // Create an instance of MainWindow
            MainWindow mainWindow = new MainWindow(uidoc);

            // Create an ExternalEvent passing this instance as the handler
            externalEvent = ExternalEvent.Create(this);

            //we will pass in doc and uidoc because these are already being accessed in the mainwindow xaml code
            IList<Reference> pickedObjs = uidoc.Selection.PickObjects(ObjectType.Element, "Select Elements");
            // Store the count of pickedObjs in the property
            PickedObjectsCount = pickedObjs.Count;

            // Trigger the ExternalEvent
            externalEvent.Raise();

            // Returning Result.Succeeded here means that the command is completed
            return Result.Succeeded;
        }

        public void Execute(UIApplication app)
        {

        }

        public string GetName()
        {
            return "YourCommandName";
        }
    }
}

 

I then implemented this onto the button click

        private void GatherBeamsButton_Click(object sender, RoutedEventArgs e)
        {
            // Create an instance of YourCommandName
            YourCommandName command = new YourCommandName();


            // Execute the ExternalCommand
            command.Execute(uidoc.Application);

            // Access the value of x (PickedObjectsCount)
            int x = command.PickedObjectsCount;

 

Same error though, never able to select anything.




Message 3 of 5
ricaun
in reply to: retug_austin

I believe your problem is in the way you are showing your window.

 

Using ShowDialog gonna block Revit until you close/hide your Window.

 

One way would be to Hide your Window before you run the selection, and ShowDialog after the selection.

 

public partial class MainView : Window
{
    private readonly UIApplication uiapp;

    public MainView(UIApplication uiapp)
    {
        InitializeComponent();
        this.uiapp = uiapp;
    }

    private void Button_Click(object sender, RoutedEventArgs e)
    {
        UIDocument uidoc = uiapp.ActiveUIDocument;
        this.Hide();
        try
        {
            var elements = uidoc.Selection.PickObjects(ObjectType.Element, "Select Elements");
            Console.WriteLine(elements.Count);
        }
        catch (Exception)
        {

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

        new MainView(uiapp).ShowDialog();

        return Result.Succeeded;
    }
}

 

Another way would be to use modeless windows, using the Show that does not block Revit. Is a more advanced way to work with Windows and by looking at your code everything gonna break, so use Hide/ShowDialog 😀

Luiz Henrique Cassettari

ricaun.com - Revit API Developer

AppLoader EasyConduit WireInConduit ConduitMaterial CircuitName ElectricalUtils

Message 4 of 5
retug_austin
in reply to: retug_austin

@ricaun, thanks, this seems to do the trick, appreciate your help.

 

I ended up forgoing the second way, with the IExternalCommand and just placed the code in the button press. 

 

Is there any benefits to firing up the separate IExternalCommand? Any best practices to follow here?

 

I also noticed with my application being up, the user cannot interact with Revit at all, it's basically locked down. Is this due to the ShowDialog/Show you mentioned? I would like for the user to interact with the revit model with the application up. Would modeless solve this problem? Let me know if there are any good resources that cover revit states, I need to do some more reading to better understand this.

Message 5 of 5
ricaun
in reply to: retug_austin

The `IExternalCommand` is designed for Revit when the user interacts with some Revit UI, usually PushButton.

 

I usually create a class with the UIApplication in the constructor, and I can reuse this class in the `IExternalCommand` or `IExternalEventHandler`.

 

The `IExternalEventHandler` is used by the modeless windows, to execute Revit code. By default Revit is not allowed to run Revit code at any time, only in the Revit time or in Revit Context, `IExternalEventHandler` gonna ensure the Revit Context.

 

I have this sample RevitAddin.ExternalEventExample with the implementation to delete elements using modeless windows and ExternalEvent.

Yes, using Show gonna make your Windows modeless and you gonna need to use `IExternalEventHandler` to run Revit code.

 

Luiz Henrique Cassettari

ricaun.com - Revit API Developer

AppLoader EasyConduit WireInConduit ConduitMaterial CircuitName ElectricalUtils

Can't find what you're looking for? Ask the community or share your knowledge.

Post to forums  

Rail Community


Autodesk Design & Make Report