ぱぇぽぃ2 ? Blog Archive ? Python getter, setter
の続き、上手くいったので覚書に。
ObservableCollection を作って ListView で DataBinding させる。
Silverlight Dynamic Languages SDK – Discussions
ほう、こうすればいいんだ。
コレを IronPython 2.6 から使える property setter でやってみる。
{ironpythondir}/Tutorial/pyevent.py
をソースコードと同じ場所にコピー
追記と小変更
pyevent.py の import はこうすればコピー不要
import sys
tutorial_path = IO.Path.GetDirectoryName(sys.executable) + "\\Tutorial"
sys.path.insert(0, tutorial_path)
from pyevent import *
データトリガーなんかをコードで行う方法が解らないので XAML で。
以下ソースコード
#-*- coding:utf-8 -*-
import clr
clr.AddReferenceByPartialName("PresentationCore")
clr.AddReferenceByPartialName("PresentationFramework")
clr.AddReferenceByPartialName("WindowsBase")
from System import *
from System.Windows import *
from System.Windows.Controls import *
from System.Collections.ObjectModel import *
from System.ComponentModel import *
from System.Windows.Markup import XamlReader
# Search pyevent.py
import sys
tutorial_path = IO.Path.GetDirectoryName(sys.executable) + "\\Tutorial"
sys.path.insert(0, tutorial_path)
from pyevent import *
listview_str = """<ListView
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
<ListView.Resources>
<Style x:Key="sensitive" TargetType="TextBlock">
<Style.Triggers>
<DataTrigger Binding="{Binding Path=show}" Value="False">
<Setter Property="Foreground" Value="Silver" />
</DataTrigger>
</Style.Triggers>
</Style>
<DataTemplate x:Key="tpl_show">
<CheckBox IsChecked="{Binding Path=show}" />
</DataTemplate>
<DataTemplate x:Key="tpl_name">
<TextBlock Text="{Binding Path=name}" TextTrimming="CharacterEllipsis"
Style="{StaticResource sensitive}" />
</DataTemplate>
</ListView.Resources>
<ListView.View>
<GridView>
<GridViewColumn Header="Show" CellTemplate="{StaticResource tpl_show}" />
<GridViewColumn Header="Name" CellTemplate="{DynamicResource tpl_name}" />
</GridView>
</ListView.View>
</ListView>"""
class NotifyPropertyChangedBase(INotifyPropertyChanged):
"""
http://sdlsdk.codeplex.com/Thread/View.aspx?ThreadId=30322
"""
PropertyChanged = None
def __init__(self):
(self.PropertyChanged, self._propertyChangedCaller) = make_event()
def add_PropertyChanged(self, value):
self.PropertyChanged += value
def remove_PropertyChanged(self, value):
self.PropertyChanged -= value
def OnPropertyChanged(self, propertyName):
self._propertyChangedCaller(self, PropertyChangedEventArgs(propertyName))
class MyData(NotifyPropertyChangedBase):
"""
use setter getter.
IronPython 2.6 or later.
"""
@property
def name(self):
return self._name
@name.setter
def name(self, value):
self._name = value
self.OnPropertyChanged("name")
@property
def show(self):
return self._show
@show.setter
def show(self, value):
self._show = value
self.OnPropertyChanged("show")
class DataBindingTest(Window):
"""
ListView DataBinding Test class
"""
def __init__(self):
self.data = ObservableCollection[MyData]()
self.Resources["data"] = self.data
self.listview = XamlReader.Parse(listview_str)
self.listview.ItemsSource = self.data
# Temporary Data
datadict = {"IronPython": True,
"C#": False,
"F#": True,
"Python": True,
"Ruby": False,
"Perl": False,
"C/C++": True }
for key in datadict.keys():
en = MyData()
en.name = key
en.show = datadict[key]
self.data.Add(en)
self.Content = self.listview
self.Title = "DataBindingTest"
self.Width = 300
self.Height = 300
# Data Check
self.Closed += self.on_closed
def on_closed(self, sender, e):
"""
Checking self.data
"""
s = ""
for data in self.data:
s += "%s: %s\r\n" % (data.name, data.show)
MessageBox.Show(s)
if __name__ == "__main__":
a = Application()
a.Run(DataBindingTest())
見事にデータ内容と表示が一致するようになりました。
CheckBox On Off で TextBlock の色が即座に変更されます。
Ruby だけ Off に変更してみた例
終了時に ObservableCollection の内容を確認。
CheckBox の値がそのままデータとなっていることが解ります。
IronPython でもコレが可能なんですね、2.6 正式版が待ちどおしい。
Enjoy!