XAML GUI Events Example

From IronPython Cookbook

Revision as of 20:09, 3 April 2008 by Daftspaniel2 (Talk | contribs)

This is a simple XAML example which loads up the XML defined interface and then dynamically links up event handlers.

The reusable function Waddle traverses the object in the GUI stack and creates a dictionary of dictionaries for the controls found with a Name attribute set.

This gives quick and easy access to controls to add event handlers and so on. For example,

controls['Button']['NewSite'].Click += sayhello2

Run the example and pressing any of the Plugin buttons will print out 'sayhello' and the 'New Site' button will also print 'sayhello2'.


import clr
clr.AddReference("PresentationFramework, Version=, Culture=neutral, PublicKeyToken=31bf3856ad364e35")
clr.AddReference("PresentationCore, Version=, Culture=neutral, PublicKeyToken=31bf3856ad364e35")
from System.IO import StringReader
from System.Xml import XmlReader
from System.Windows.Markup import XamlReader, XamlWriter
from System.Windows import Window, Application
from System.Windows.Controls import Button, Canvas

xaml = """<Window
    Title="Enterprisey-FireDrop Express" Width="640" Height="480"

       <StackPanel DockPanel.Dock ="Left">
    <Thickness Left="10" Top="10" Right="10" Bottom="10"/>
                RadiusX="{Binding ElementName=RadiusX, Path=Value}" 
                RadiusY="{Binding ElementName=RadiusY, Path=Value}"> 
                    <GradientStop Color="#FAFAFAFA" Offset="0"/>
                    <GradientStop Color="#B2171F6E" Offset="0.971"/>
        <Expander IsExpanded ="True" Header ="Site">
        <StackPanel x:Name="N">
        <Button Content="Open">
        <Button Content="New" x:Name="NewSite">
        <Button Content="Build">
        <Button Content="Publish">
        <Button Content="ViewOnline">
        <Expander IsExpanded ="True" Header ="Entry">
        <Button Content="Open">
        <Button Content="New">
        <Button Content="Save">
        <Button Content="Preview">
        <Expander IsExpanded ="True" Header ="Plugins">
        <Button Content="ScratchPad" x:Name="ScratchPad">
        <Button Content="Photo" x:Name="Photo">
        <Button Content="GR Shared Items" x:Name="Shared">

        <ListBox Margin="3,3,0,3" Padding="2" HorizontalAlignment="Left" Width="90">
            <ListBoxItem>Document 1</ListBoxItem>
            <ListBoxItem>Document 2</ListBoxItem>
            <ListBoxItem>Document 3</ListBoxItem>
        <RichTextBox Padding="2" Background="Thistle" Margin="97,3,3,3" />



# 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 str(c).find("System.Windows.Controls.")>-1 and hasattr(c,"Name") and c.Name.Length>0:
        ControlType = s[s.find("'")+1:s.rfind("'")]
        if not d.has_key(ControlType):
            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)

# Test Functions.
def sayhello(s,e):
    print "sayhello"
def sayhello2(s,e):
    print "sayhello2"

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