ぱぇぽぃ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!