Select model element with user interface

Hi all,

i have started with xaml but for me it is quite hard to connect xaml with python code.

I want that the user needs to select a revit element/face/edge whatever, when clicking the button.
Python in Dynamo works like this here:

import clr

#Import the Revit API
clr.AddReference(‘RevitAPI’)
clr.AddReference(‘RevitAPIUI’)
import Autodesk
from Autodesk.Revit.DB import *
from Autodesk.Revit.UI import *

#Import DocumentManager and TransactionManager
clr.AddReference(‘RevitServices’)
import RevitServices
from RevitServices.Persistence import DocumentManager

doc = DocumentManager.Instance.CurrentDBDocument
uiapp = DocumentManager.Instance.CurrentUIApplication
uidoc = uiapp.ActiveUIDocument

sel = uidoc.Selection.PickObject(Autodesk.Revit.UI.Selection.ObjectType.Element)

OUT = sel

What i tried with the .py file in the extension file is a def that i can call in xaml:

dependencies

import clr

clr.AddReference(‘System.Windows.Forms’)

clr.AddReference(‘IronPython.Wpf’)

#Import the Revit API

clr.AddReference(‘RevitAPI’)

clr.AddReference(‘RevitAPIUI’)

import Autodesk

from Autodesk.Revit.DB import *

from Autodesk.Revit.UI import *

#Import DocumentManager and TransactionManager

clr.AddReference(‘RevitServices’)

import RevitServices

from RevitServices.Persistence import DocumentManager

find the path of ui.xaml

from pyrevit import UI

from pyrevit import script

xamlfile = script.get_bundle_file(‘ui.xaml’)

import WPF creator and base Window

import wpf

from System import Windows

doc = DocumentManager.Instance.CurrentDBDocument

uiapp = DocumentManager.Instance.CurrentUIApplication

uidoc = uiapp.ActiveUIDocument

class MyWindow(Windows.Window):

def __init__(self):

    wpf.LoadComponent(self, xamlfile)

def selection(self, sender, args)

    sel = uidoc.Selection.PickObject(Autodesk.Revit.UI.Selection.ObjectType.Element)

let’s show the window (modal)

MyWindow().ShowDialog()

This doesn’t work

Hope somebody can help

Can you provide us with the output of your code? An error message of some kind? Are you running this in dynamo or in python?

A few things that are hazy in your description is:

  1. when you call
wpf.LoadComponent(self, xamlfile)

Are you absolutely sure that the xamlfile path has been provided? (check it with a print statement if need be)

  1. It might be that you call your selection function ‘selection’ it could be that this variable is provided as a variable in your scope. try renaming it in your xaml and your python file. Perhaps something like “onclick_selection”?

I’ll be able to help you better once you provide your console output.

Hey @GertjanVDB,

thanks for your reply.

i tried a bit more and made my code hopefully a bit more structured.

  1. the filepath for the xaml file is defenetly provided since my window pops up when i comment out 1 line of code :slight_smile:

  2. i changed the name of the function a couple of times now

Here is the error:

It shows up when i click the Select face button a second time. But when i click it the first time everything in Revit is greyed out, i cannot click anything and i cannot click a face neither (which is what i want to achieve)

# dependencies

import clr

clr.AddReference('System.Windows.Forms')

clr.AddReference('IronPython.Wpf')

#Import the Revit API

import clr

import sys

sys.path.append('C:\Program Files (x86)\IronPython 2.7\Lib')

import System

from System import Array

from System.Collections.Generic import *

clr.AddReference('ProtoGeometry')

from Autodesk.DesignScript.Geometry import *

clr.AddReference("RevitNodes")

import Revit

clr.ImportExtensions(Revit.Elements)

clr.ImportExtensions(Revit.GeometryConversion)

clr.AddReference("RevitServices")

import RevitServices

from RevitServices.Persistence import DocumentManager 

from RevitServices.Transactions import TransactionManager 

clr.AddReference("RevitAPI")

clr.AddReference("RevitAPIUI")

import Autodesk 

from Autodesk.Revit.DB import *

from Autodesk.Revit.UI import *

# find the path of ui.xaml

from pyrevit import UI

from pyrevit import script

from pyrevit import forms

xamlfile = script.get_bundle_file('ui.xaml')

# import WPF creator and base Window

import wpf

from System import Windows

doc = DocumentManager.Instance.CurrentDBDocument

uiapp = DocumentManager.Instance.CurrentUIApplication 

app = uiapp.Application 

uidoc = uiapp.ActiveUIDocument

class PrintSheetsWindow(forms.WPFWindow):

    def __init__(self):

        wpf.LoadComponent(self, xamlfile)

                

    def face(self, sender, args):

        #this does not work

        a = uidoc.Selection.PickObject(Autodesk.Revit.UI.Selection.ObjectType.Face) 

        #Just a hello world functioanlity to test out def and xaml --> works (y)

        name = self.textbox.Text

        self.label.Content = "Hello {}".format(name)

        

# let's show the window (modal)

PrintSheetsWindow().ShowDialog()
1 Like

Oh what i just found out is that when i click the “Select face” button the first time and then close the window, then i can select a face

I know this is an old post, but for future reference, this problem has been solve in a different post: https://discourse.pyrevitlabs.io/t/select-model-element-from-ui-upon-button-click/1512

You hide and show the window before and after your selection with:
self.Hide()
self.Close()

so your code looks something like this:

def face(self, sender, args):
    self.Hide()
    a = uidoc.Selection.PickObject(Autodesk.Revit.UI.Selection.ObjectType.Face) 
    self.Close()

2 Likes

I noticed a mistake in my previous post, this is how I do it now:

def face(self, sender, args):
    self.Hide()
    a = uidoc.Selection.PickObject(Autodesk.Revit.UI.Selection.ObjectType.Face) 
    self.ShowDialog()

By using ShowDialog(), you create a modal window once again. After some testing, I believe this gives better results than a modeless window.

2 Likes

wait , so hiding the window also stops it from blocking revit? I did not know that