How Isolate Elements by WinForms

Hello! I would like to ask a follow up question on this thread Window WPF with work in Revit - #7 by c.poupin
Can you please tell me if I can make each element I select in the dropdown list immediately isolated? With the help
“uidoc.ActiveView.IsolateElementTemporary(itemId)” after
“uidoc.Selection.SetElementIds(ListElementId)”
it was possible to do this, but it is not possible to write in the code so that the view is restored back before pressing the next element.
And one more question. Please tell me how to make the winform window always on top of the Revit window?
P.S. Friends, it turned out to alternately isolate elements by writing “uidoc.ActiveView.DisableTemporaryViewMode(TemporaryViewMode.TemporaryHideIsolate)” before these two lines.
I will be grateful for the answer to the second question.

You have to create function that will be executed when SelectionChanged of dropdown triggered. In that function first of all uidoc.ActiveView.DisableTemporaryViewMode(TemporaryViewMode.TemporaryHideIsolate) and then uidoc.ActiveView.IsolateElementTemporary(itemId)

In init method of class => dropdown.SelectionChanged += your function

1 Like

if you want to make the wpf always on top, you can add
Topmost=“True”
inside

<windows>
1 Like


Thanks friends for the tip. Since I’m a beginner in Windows Forms, I didn’t really understand this “dropdown.SelectionChanged += your function”… But I managed to do what I was looking for in a different way. Special thanks for Topmost, it helped! I also had a few new questions about the same script. So I understand it’s better to create a new topic than to ask them here? For now, I’ll ask, if there are tips to move, I’ll create a new topic.
It turned out to make a drop-down list with two elements that, when selected in the table, are isolated and scaled in the center of the screen. But now, with any revit command or escape key, the view is restored to the original without any isolated elements.
As far as I understand - the reason is the absence of a transaction - Revit does not execute the isolation of elements as a command. Is it possible to somehow correctly register a transaction here for executing commands with Revit?

import clr
import sys
import System
sys.path.append(r'C:\Program Files (x86)\IronPython 2.7\Lib')
sys.path.append(r'C:\Program Files (x86)\IronPython 2.7\DLLs')

#import Revit API
clr.AddReference('RevitAPI')
import Autodesk
from Autodesk.Revit.DB import *
import Autodesk.Revit.DB as DB

clr.AddReference('DSCoreNodes')
import DSCore

#import net library
from System.Collections.Generic import List

#import transactionManager and DocumentManager (RevitServices is specific to Dynamo)
clr.AddReference('RevitServices')
import RevitServices
from RevitServices.Persistence import DocumentManager
from RevitServices.Transactions import TransactionManager

doc = DocumentManager.Instance.CurrentDBDocument
uiapp = DocumentManager.Instance.CurrentUIApplication
uidoc = uiapp.ActiveUIDocument
app = uiapp.Application
sdkNumber = int(app.VersionNumber)
rpt = DSCore.List.OfRepeatedItem
tsp = DSCore.List.Transpose
try:
        clr.AddReference("IronPython.Wpf")
        clr.AddReference('System.Core')
        clr.AddReference('System.Xml')
        clr.AddReference('PresentationCore')
        clr.AddReference('PresentationFramework')
except IOError:
        raise

from System.IO import StringReader
from System.Windows.Markup import XamlReader, XamlWriter
from System.Windows import Window, Application
import wpf

cats = doc.Settings.Categories
catsN = sorted([c.Name for c in cats])
lst1 = []
walls_1 = UnwrapElement(FilteredElementCollector(doc, doc.ActiveView.Id).OfClass(Wall).ToElements())
floors_1 =UnwrapElement(FilteredElementCollector(doc, doc.ActiveView.Id).OfClass(Floor).ToElements())
c1 = [i for i in cats if i.Name == "Structural Columns"][0]
bc1 = System.Enum.ToObject(BuiltInCategory, c1.Id.IntegerValue)
columns_1 = FilteredElementCollector(doc, doc.ActiveView.Id).OfCategory(bc1).WhereElementIsNotElementType().ToElements()
c2 = [i for i in cats if i.Name == "Structural Framing"][0]
bc2 = System.Enum.ToObject(BuiltInCategory, c2.Id.IntegerValue)
framing_1 = FilteredElementCollector(doc, doc.ActiveView.Id).OfCategory(bc2).WhereElementIsNotElementType().ToElements()
c3 = [i for i in cats if i.Name == "Structural Foundations"][0]
bc3 = System.Enum.ToObject(BuiltInCategory, c3.Id.IntegerValue)
foundations_1 = FilteredElementCollector(doc, doc.ActiveView.Id).OfCategory(bc3).WhereElementIsNotElementType().ToElements()
c4 = [i for i in cats if i.Name == "Ceilings"][0]
bc4 = System.Enum.ToObject(BuiltInCategory, c4.Id.IntegerValue)
ceilings_1 = FilteredElementCollector(doc, doc.ActiveView.Id).OfCategory(bc4).WhereElementIsNotElementType().ToElements()
c5 = [i for i in cats if i.Name == "Walls"][0]
bc5 = System.Enum.ToObject(BuiltInCategory, c5.Id.IntegerValue)
walls_1 = FilteredElementCollector(doc, doc.ActiveView.Id).OfCategory(bc5).WhereElementIsNotElementType().ToElements()
c6 = [i for i in cats if i.Name == "Floors"][0]
bc6 = System.Enum.ToObject(BuiltInCategory, c6.Id.IntegerValue)
floors_1 = FilteredElementCollector(doc, doc.ActiveView.Id).OfCategory(bc6).WhereElementIsNotElementType().ToElements()
inter1 = []
for i in walls_1:
	k = [i,FilteredElementCollector(doc).OfCategory(bc6).WherePasses(ElementIntersectsElementFilter(i)).ToElements()]
	inter1.append(k)
inter2 = [[rpt(i[0],len(i[1])),i[1]] for i in inter1]
inter3 = [tsp(i) for i in inter2]
inter4 = [i1[0] for i in inter3 for i1 in i]
inter5 = [i1[1] for i in inter3 for i1 in i]
class MyForm(Window):

        LAYOUT = """
                <Window xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
                        Title="Window2"
                        Width="650"
                        Topmost="True"
                        Height="700">
                        <Grid>
                                <Label
                                        Grid.Column="0"
                                        Grid.Row="0"
                                        HorizontalAlignment="Left"
                                        VerticalAlignment="Top"
                                        Margin="14,16,0,00"
                                        Width="130"
                                        Height="29"
                                        x:Name="ClickSelect"
                                        Content="Click to Select" />
                                <Button
                                        Content="Close"
                                        Grid.Column="2"
                                        Grid.Row="2"
                                        HorizontalAlignment="Right"
                                        VerticalAlignment="Bottom"
                                        Margin="0,0,16,16"
                                        Width="96"
                                        Height="24"
                                        x:Name="button1"
                                        Click="button1_Click" />
                                <ListBox
                                        x:Name="listBox1"
                                        SelectionChanged="listBox0_SelectionChanged"
                                        Grid.Row="1"
                                        Grid.Column="0"/>
                                <ListBox
                                        x:Name="listBox0"
                                        SelectionChanged="listBox1_SelectionChanged"
                                        Grid.Row="1"
                                        Grid.Column="1"
                                        Grid.ColumnSpan="1"/>
                                <ListBox
                                        x:Name="listBox2"
                                        SelectionChanged="listBox2_SelectionChanged"
                                        Grid.Row="1"
                                        Grid.Column="2"
                                        Grid.ColumnSpan="1"/>
 
								<Grid.ColumnDefinitions>
                                        <ColumnDefinition
                                                Width="160 px" />
                                        <ColumnDefinition
                                                Width="160" />
                                        <ColumnDefinition
                                                Width="180" />
                                </Grid.ColumnDefinitions>
                                <Grid.RowDefinitions>
                                        <RowDefinition
                                                Height="50 px" />
                                        <RowDefinition
                                                Height="500" />
                                        <RowDefinition
                                                Height="100" />
                                </Grid.RowDefinitions>
                        </Grid>
                </Window>"""

        def __init__(self):
                self.ui = wpf.LoadComponent(self, StringReader(MyForm.LAYOUT))
                for i,j in zip(inter4,inter5):
                        item = System.Windows.Controls.ListBoxItem()
                        item.Content = i.Name
                        item.Tag = i.Id
                        self.ui.listBox1.Items.Add(item)
                        item1 = System.Windows.Controls.ListBoxItem()
                        item1.Content = j.Name
                        item1.Tag = j.Id
                        self.ui.listBox0.Items.Add(item1)
                        item2 = System.Windows.Controls.ListBoxItem()
                        item2.Content = [i,j]
                        item2.Tag = [i.Id,j.Id]
                        self.ui.listBox2.Items.Add(item2)

        def button1_Click(self, sender, e):
        		self.Close()

        def listBox0_SelectionChanged(self, sender, e):
                itemId = self.ui.listBox0.SelectedItem.Tag

        def listBox1_SelectionChanged(self, sender, e):
                itemId = self.ui.listBox0.SelectedItem.Tag

        def listBox2_SelectionChanged(self, sender, e):
                itemId = self.ui.listBox2.SelectedItem.Tag
                print((self.ui.listBox2.SelectedItem.Tag)) 
                elem = [doc.GetElement(i) for i in itemId]
                uidoc.ActiveView.DisableTemporaryViewMode(TemporaryViewMode.TemporaryHideIsolate)
                uidoc.Selection.SetElementIds(List[ElementId](itemId))
                uidoc.ActiveView.IsolateElementsTemporary(List[ElementId](itemId))
                uidoc.RefreshActiveView()
		uidoc.GetOpenUIViews()[0].ZoomToFit()
				
form = MyForm()
form.Show()

Is it even possible to inject a transaction into the body of a function in a class? It doesn’t work and gives me an error

no,

a workaround is to implement an IExternalEventHandler Interface

some examples

https://pythoncvc.net/?p=247

Otherwise, without transaction, instead of isolating the element, you can zoom in on it with uidoc.ShowElements()

2 Likes

Thanks for the links! I will study, I think that I need the first scenario. I just need to figure it out. Might be able to come up with something.