Skip to content Skip to sidebar Skip to footer

GUI Development With IronPython And Visual Studio 2010

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 to use Vi

Solution 1:

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.


Solution 2:

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.


Post a Comment for "GUI Development With IronPython And Visual Studio 2010"