Need help with my first xaml file

Hello,
I am trying to learn how to use WPF (xaml) alongside my scripts.
This is the very simple xaml file:

<?xml version="1.0" encoding="utf-8"?>
<Window xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
	Title="Find Views for Line Styles"
	Height="150"
	Width="300"
	WindowStartupLocation="CenterScreen">
	<StackPanel
		Grid.Row="2"
		VerticalAlignment="Top"
		Margin="10,5,10,5">
		<Button
			x:Name="SelectLineButton"
			Content="Select a line in your model"
			Click="SelectLineButton_Click"
			Margin="5 20 5 20" />
		<!-- !Buttons -->
		<Grid>
			<Grid.ColumnDefinitions>
				<ColumnDefinition
					Width="*" />
				<ColumnDefinition
					Width="*" />
			</Grid.ColumnDefinitions>
			<Button
				Click="OK_Click"
				Margin="10 0 10 0"
				Grid.Column="0"
				Content="OK" />
			<Button
				Click="CancelButton_Click"
				Margin="10 0 10 0"
				Grid.Column="1"
				Content="Cancel" />
		</Grid>
	</StackPanel>
</Window>

and this is the python code:

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

import wpf
from System import Windows

class CustomISelectionFilter(ISelectionFilter):
    def AllowElement(self, element):
        if type(element) == DetailLine:
            return True
    

class Window1 (WPFWindow):
    def __init__(self, xaml_file_name):
        WPFWindow.__init__(self, xaml_file_name)
        self.ShowDialog()
       

    def SelectLineButton_Click(self,sender,e):
        try:
            self.Hide()
            line_sel_ref = selection.PickObject(ObjectType.Element, CustomISelectionFilter())
            line_sel = uidoc.Document.GetElement(line_sel_ref)
            self.Show()
            return line_sel
        except:
            UI.TaskDialog.Show("Operation canceled","Canceled by the user")
    
    def OK_Click (self, sender, e):
        UI.TaskDialog.Show("Hello Revit")
        
        
    
    def CancelButton_Click(self, sender, e):
        self.Close()

form = Window1('ui.xaml')

I can click on the “select a line…” button and pick a line in the model, but when i click in the “OK” button, my revit crash.
I have removed the code, replaced with a simple “Hello Revit” and still crashes.
Could you please help me understand the issue. Thanks

1 Like

HI @hoss53,
I believe this won’t solve your issue, but you can’t return from a method called by a GUI event.

You need to turn line_sel into a Window1 attribute, so that you can retrieve it with form.line_sel (or self.line_sel if you need it inside the class).

BTW, really bad naming if you ask me! Try to be as descriptive as possible with your classes and variables names. Your 3 months self from now will thanks you if you make the code clear :wink:

1 Like

Thanks for the help regarding the naming etc.
I am not developing any tools, just trying to understand how things work when comes to using own user interface.
Going back to my original example, OK button has been set to just show a message as follows

    def OK_Click (self, sender, e):
        UI.TaskDialog.Show("Hello Revit", "Hello Revit)

If I run the script and click on ok, without touching anything else, dialog box shows with the set message.
But if I run the script and click on “Select a line in your model” button and pick a line and click on OK, my Revit crashes
So I am guessing I need to use external event somewhere. Would be grateful if someone point me to an example please. Thanks

I think I found an answer to my question
I created a fuction “select_line_inmodel” for selecting the object and using external event handler from pyRevitMEP External Event
changed the code for the button that ask user to pick object as follow

def SelectLineButton_Click(self, sender, e):
self.Hide()
customizable_event.raise_event(self.select_line_inmodel)
self.Show()

and all seems to be working fine now

1 Like