XAML GUI Events Example

From IronPython Cookbook

Revision as of 19:55, 3 April 2008 by Daftspaniel2 (Talk | contribs)
(diff) ← Older revision | Current revision (diff) | Newer revision → (diff)

This is a simple XAML example which loads up the XML defined interface and then dynamically links up event handlers. The 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. 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