I\'m teaching an introductory class to programming and GUI development using Python, and have found that the least overwhelming solution for students new to programming is t
You need to walk through all of the objects and create the easier/understandable references using a function like.
#
# Waddle returns a dictionary of Control types e.g. listbox, Button.
# Each Entry is a dictionary of Control Instance Names i.e.
# controls['Button']['NewSite'] returns the button control named NewSite
# Controls should have Unique names and only those with a Name attrib set
# will be included.
#
def Waddle(c, d):
s = str(c.__class__)
if "System.Windows.Controls." in str(c) and hasattr(c,"Name") and c.Name.Length>0:
ControlType = s[s.find("'")+1:s.rfind("'")]
if ControlType not in d:
d[ControlType] = {}
d[ControlType][c.Name] = c
if hasattr(c,"Children"):
for cc in c.Children:
Waddle(cc, d)
elif hasattr(c,"Child"):
Waddle(c.Child, d)
elif hasattr(c,"Content"):
Waddle(c.Content, d)
if __name__ == "__main__":
xr = XmlReader.Create(StringReader(xaml))
win = XamlReader.Load(xr)
controls = {}
Waddle(win, controls)
#Make all Named buttons do something!
for butt in controls['Button']:
controls['Button'][butt].Click += sayhello
#Make one button do something.
controls['Button']['NewSite'].Click += sayhello2
Application().Run(win)
See http://www.ironpython.info/index.php/XAML_GUI_Events_Example for the above code and a complete example.
In IronPython 2.7 the wpf.LoadComponent method will wire up any properties with the same name as the XAML UI elements. If you are using IronPython 2.6 then you would need to use the code as suggested by WombatPM. So with IronPython 2.7 if you use the following XAML:
<Window
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="IronPyWpf" Height="300" Width="300">
<Grid>
<Button x:Name="button" Content="Button" Height="23" HorizontalAlignment="Left" Margin="103,226,0,0" VerticalAlignment="Top" Width="75" />
<TextBox x:Name="textbox" Height="182" HorizontalAlignment="Left" Margin="24,21,0,0" VerticalAlignment="Top" Width="237" />
</Grid>
</Window>
Then you can define two properties called button and textbox to access the UI elements:
class MyWindow(Window):
def __init__(self):
wpf.LoadComponent(self, 'IronPyWpf.xaml')
self._button.Content = 'My Button'
self._textbox.Text = 'My Text'
def get_button(self):
return self._button
def set_button(self, value):
self._button = value
button = property(get_button, set_button)
def get_textbox(self):
return self._textbox
def set_textbox(self, value):
self._textbox = value
textbox = property(get_textbox, set_textbox)
In fact it seems that you can simplify the code even further by removing the property definitions:
class MyWindow(Window):
def __init__(self):
wpf.LoadComponent(self, 'IronPyWpf.xaml')
self.button.Content = 'My Button'
self.textbox.Text = 'My Text'
Unfortunately Visual Studio seems to crash, as you have already seen, with a null reference exception when you try to edit the XAML and give the UI elements a name.