If you are new to WPF, it’s going to be a bumpy ride in the beginning.
Do you really need a custom UI, or is it sufficient to use pre-written forms in pyRevit or rpw package?
Check out Effective Inputs in pyRevit docs, maybe SelectFromList will be enough for you. It’s quite well documented.
I’ve shared my 2 cents on pyRevit input forms here: Login | MailerLite
You might like the idea of using FlexForm from rpw package.
If you really need custom UI, you should be comfortable writing classes in python.
You can try to look at my example in my github repository of EF-Tools
lib → GUI → select_from_dict.py select_from_dict.xaml (or something along these lines)
I made it when I was still learning about WPF, so it’s not perfect, but it works and I am lazy to rewrite it nicer.
Thanks @ErikFrits
I am not much familiar writing classes in python . I have used C# classes and an intermediate in WPF. So I think best way to get a result is to use pre-written forms in PyRevit as you suggested. Meanwhile could you please give me an example how to bind combo box using python classes.
from pyrevit import revit
from pyrevit import forms,script,EXEC_PARAMS,UI
from Autodesk.Revit.UI.Selection import *
import clr
clr.AddReference('System.Windows.Forms')
clr.AddReference('IronPython.wpf')
import clr
import sys
clr.AddReference('RevitAPI')
from Autodesk.Revit.DB import *
from Autodesk.Revit.DB.Electrical import*
from Autodesk.Revit.DB.Mechanical import*
from Autodesk.Revit.DB.Architecture import *
from Autodesk.Revit.DB.Analysis import *
uiapp = __revit__
uidoc = uiapp.ActiveUIDocument
doc = uiapp.ActiveUIDocument.Document
import wpf #This is the wpf engine which is coming from IronPython.wpf which will be used to load xaml file
from System import Windows
from pyrevit import script
xamlfile = script.get_bundle_file('ui.xaml') #This will search this ui file in the current bundle and get that file.
#Collectors
Anno_Family_Names = []
Generic_Anno_Famlies = FilteredElementCollector(doc).OfCategory(BuiltInCategory.OST_GenericAnnotation).WhereElementIsElementType().ToElements()
class CustomISelectionFilter(ISelectionFilter):
def __init__(self, category_name):
self.category_name = category_name
def AllowElement(self, e):
if e.Category.Name == self.category_name:
return True
else:
return False
def AllowReference(self, ref, point):
return true
class MyWindow(Windows.Window):
def __init__(self):
wpf.LoadComponent(self,xamlfile) #self is the instance of the class and we are loading xaml file into that instance
self.vm = ViewModel()
def btn_Click_SelectPipe(self,sender,args):
try:
self.Hide()
Pipe_Sel = uidoc.Selection.PickObject(ObjectType.Element,CustomISelectionFilter("Pipes"),"Select a Pipe")
self.Show()
except:
UI.TaskDialog.Show("Operation canceled","Canceled by the user")
__doc__ = """ This tool will place flow aroows in pipes.
Tip : Select the pipe in network and then run the script.
Shift + Click : This mode will place arrows in the reverse direction."""
__title__ = 'Pipe \n Flow Arrow'
__author__ = 'Jobin Sunny'
MyWindow().ShowDialog()