Select Elements by category on Subform

I can pickobjecks by category in one Form, but when try get it on Form2 (Subform of Mainform)
Revit is Freeze.
Please explain it.

Thank Advance!

#Get in 1 form, run in Ironpython2
import clr, System
clr.AddReference('RevitAPI')
from Autodesk.Revit.DB import *
clr.AddReference('RevitAPIUI')
from Autodesk.Revit.UI import *
from Autodesk.Revit.UI.Selection import ISelectionFilter

clr.AddReference('RevitServices')
import RevitServices
from RevitServices.Persistence import DocumentManager
from RevitServices.Transactions import TransactionManager
doc = DocumentManager.Instance.CurrentDBDocument
uidoc = DocumentManager.Instance.CurrentUIApplication.ActiveUIDocument

class Single_Category(ISelectionFilter):
    def __init__(self, cat):
        self.cat = cat
    def AllowElement(self, e):
        if e.Category.Name == self.cat:
            return True
        else:
            return False
    def AllowReference(self, ref, point):
        return true

def selects():
    elements = []
    try:
        pickeds = uidoc.Selection.PickObjects(Selection.ObjectType.Element, Single_Category("Lines"),"Let's select Lines then press Finish")
        elements = [doc.GetElement(i) for i in pickeds]
    except:
        pass
    return elements

clr.AddReference('System.Windows.Forms')
clr.AddReference('System.Drawing')
import System.Drawing
import System.Windows.Forms
from System.Drawing import *
from System.Windows.Forms import *

class MainForm(Form):
    def __init__(self):
        self.InitializeComponent()
    def InitializeComponent(self):
        self._button1 = Button()
        self._button2 = Button()
        self.SuspendLayout()
        # 
        # button1##
        # 
        self._button1.Location = System.Drawing.Point(160, 230)
        self._button1.Name = "button1"
        self._button1.Size = System.Drawing.Size(70, 25)
        self._button1.TabIndex = 0
        self._button1.Text = "Cancel"
        self._button1.Click += self.Button1Click
        # button2
        # 
        self._button2.Location = System.Drawing.Point(260, 230)
        self._button2.Name = "button2"
        self._button2.Size = System.Drawing.Size(75, 25)
        self._button2.TabIndex = 0
        self._button2.Text = "Select Line"
        self._button2.Click += self.Button2Click
        # 
        # MainForm
        # 
        self.ClientSize = System.Drawing.Size(360, 270)
        self.Controls.Add(self._button1)
        self.Controls.Add(self._button2)
        self.FormBorderStyle = System.Windows.Forms.FormBorderStyle.FixedSingle
        self.MaximizeBox = False
        self.MinimizeBox = False
        self.ShowIcon = False
        self.StartPosition = System.Windows.Forms.FormStartPosition.CenterScreen
        self.Name = "MainForm"
        self.Text = "Select line"
        self.ResumeLayout(False)
        self.PerformLayout()
        #
    def Button2Click(self, sender, e):
        self.element = selects()
        self.Close()
    def Button1Click(self, sender, e):
        self.Close()

form = MainForm()
Application.Run(form)
OUT = form.element

#This is tried get Lines in SubForm

#Get in subform, run in Ironpython2
import clr, System
clr.AddReference('RevitAPI')
from Autodesk.Revit.DB import *
clr.AddReference('RevitAPIUI')
from Autodesk.Revit.UI import *
from Autodesk.Revit.UI.Selection import ISelectionFilter

clr.AddReference('RevitServices')
import RevitServices
from RevitServices.Persistence import DocumentManager
from RevitServices.Transactions import TransactionManager
doc = DocumentManager.Instance.CurrentDBDocument
uidoc = DocumentManager.Instance.CurrentUIApplication.ActiveUIDocument

class Single_Category(ISelectionFilter):
    def __init__(self, cat):
        self.cat = cat
    def AllowElement(self, e):
        if e.Category.Name == self.cat:
            return True
        else:
            return False
    def AllowReference(self, ref, point):
        return true

def selects():
    elements = []
    try:
        pickeds = uidoc.Selection.PickObjects(Selection.ObjectType.Element, Single_Category("Lines"),"Let's select Lines then press Finish")
        elements = [doc.GetElement(i) for i in pickeds]
    except:
        pass
    return elements

clr.AddReference('System.Windows.Forms')
clr.AddReference('System.Drawing')
import System.Drawing
import System.Windows.Forms
from System.Drawing import *
from System.Windows.Forms import *

class SubForm(Form):
    def __init__(self):
        self.InitializeComponent()
    def InitializeComponent(self):
        self._button1 = Button()
        self._button2 = Button()
        self.SuspendLayout()
        # 
        # button1##
        # 
        self._button1.Location = System.Drawing.Point(160, 230)
        self._button1.Name = "button1"
        self._button1.Size = System.Drawing.Size(70, 25)
        self._button1.TabIndex = 0
        self._button1.Text = "Cancel"
        self._button1.Click += self.Button1Click
        # button2
        # 
        self._button2.Location = System.Drawing.Point(260, 230)
        self._button2.Name = "button2"
        self._button2.Size = System.Drawing.Size(75, 25)
        self._button2.TabIndex = 0
        self._button2.Text = "Select Line"
        self._button2.Click += self.Button2Click
        # 
        # MainForm
        # 
        self.ClientSize = System.Drawing.Size(360, 270)
        self.Controls.Add(self._button1)
        self.Controls.Add(self._button2)
        self.FormBorderStyle = System.Windows.Forms.FormBorderStyle.FixedSingle
        self.MaximizeBox = False
        self.MinimizeBox = False
        self.ShowIcon = False
        self.Name = "SUbForm"
        self.Text = "Select line"
        self.ResumeLayout(False)
        self.PerformLayout()
        #
    def Button2Click(self, sender, e):
        self.element = selects()
        self.Close()
    def Button1Click(self, sender, e):
        self.Close()
#Mainform
class MainForm(Form):
    def __init__(self):
        self.InitializeComponent()
    def InitializeComponent(self):
        self._button1 = Button()
        self._button2 = Button()
        self.SuspendLayout()
        # 
        # button1##
        # 
        self._button1.Location = System.Drawing.Point(160, 230)
        self._button1.Name = "button1"
        self._button1.Size = System.Drawing.Size(70, 25)
        self._button1.TabIndex = 0
        self._button1.Text = "Cancel"
        self._button1.Click += self.Button1Click
        # button2
        # 
        self._button2.Location = System.Drawing.Point(260, 230)
        self._button2.Name = "button2"
        self._button2.Size = System.Drawing.Size(75, 25)
        self._button2.TabIndex = 0
        self._button2.Text = "OpenForm2"
        self._button2.Click += self.Button2Click
        # 
        # MainForm
        # 
        self.ClientSize = System.Drawing.Size(360, 270)
        self.Controls.Add(self._button1)
        self.Controls.Add(self._button2)
        self.FormBorderStyle = System.Windows.Forms.FormBorderStyle.FixedSingle
        self.MaximizeBox = False
        self.MinimizeBox = False
        self.ShowIcon = False
        self.StartPosition = System.Windows.Forms.FormStartPosition.CenterScreen
        self.Name = "MainForm"
        self.Text = "Task 1"
        self.ResumeLayout(False)
        self.PerformLayout()
        #
    def Button2Click(self, sender, e):
        self.subform = SubForm()
        self.subform.ShowDialog()
    def Button1Click(self, sender, e):
        self.Close()

form = MainForm()
Application.Run(form)

OUT = form.subform.element

Hi,

Application.Run(Form) starts a message loop on the current thread and displays the specified form. The message loop enables the form to allow it to appear responsive and have interaction with the user.
When you call ShowDialog() a modal message loop for the form is created and block the thread

try to replace

self.subform.ShowDialog()

by

self.subform.Show()

1 Like

Thank you so much!!!

I realize must not Close MainForm when active event SubForm.Show() to get subform.element

1 Like