Wednesday, December 15, 2010

IronPython & Silverlight Part III: Basic Data Binding

One of the nicest features of Silverlight is data binding. This feature allows you to perform and receive changes on the UI without explicitly adding or removing elements from UI controls. For example:

<TextBox Text="{Binding TextToDisplay}">


This XAML code says that the value of the Text property is bound to the TextToDisplay property of the of the object specified by the DataContext property.

As with other Silverlight features data binding requires you to use a .NET object with properties. We can use clrtype to take advantage of this feature with IronPython.

For example, say that we want to bind a text property to a Python object to a TextBox:

<UserControl x:Class="System.Windows.Controls.UserControl"
xmlns="http://schemas.microsoft.com/client/2007"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
<StackPanel Width="300" x:Name="layout_root" Background="White">
<TextBox x:Name="my_text_box"
Text="{Binding text_to_display, Mode=TwoWay}" />
<Button x:Name="my_button" Content="Show text"/>
</StackPanel>
</UserControl>



The app.py file looks like this:


from System.Windows import Application
from System.Windows.Controls import UserControl
import System
import clrtype
from System.Windows import MessageBox

class MyData:
__metaclass__ = clrtype.ClrClass

def __init__(self):
self.text = 'Initial text'

@property
@clrtype.accepts()
@clrtype.returns(System.String)
def text_to_display(self): return self.text


@text_to_display.setter
@clrtype.accepts(System.String)
@clrtype.returns()
def text_to_display(self, value):
self.text = value

class App:

def handle_click(self, sender, event_args):
MessageBox.Show(self.data.text)

def __init__(self):
self.data = MyData()
self.root = Application.Current.LoadRootVisual(UserControl(), "app.xaml")
self.root.my_text_box.DataContext = self.data
self.root.my_button.Click += lambda s,ea: self.handle_click(s,ea)

theApp = App()


Here the definition of MyData is decorated with the information on how to generate the .NET class elements to be exposed .


Since the binding is declarated as TwoWay modifications to the TextBox are reflected in the data instance.




As with Part I and Part II of these series, IronPython 2.7 beta 1 is used for all examples.