Hi Curt, Thanks, just what I needed and the performance is definitely acceptable if you keep trackedNames to a minimum.
--Steve ----- Original Message ----- From: "Curt Hagenlocher" <[email protected]> To: "Discussion of IronPython" <[email protected]> Sent: Wednesday, August 5, 2009 8:35:15 PM GMT -05:00 US/Canada Eastern Subject: Re: [IronPython] DataBinding from IronPython Object to WPF Property Python's __setattr__ hook makes INotifyPropertyChanged easy to implement if you're willing to pay the performance penalty. Just derive from a class like this one: class PropertyChangeNotifier(INotifyPropertyChanged): def __init__(self, *trackedNames): self._PropertyChanged, self._OnPropertyChanged = pyevent.MakeEvent() self._trackedNames = trackedNames def add_PropertyChanged(self, handler): self._PropertyChanged += handler def remove_PropertyChanged(self, handler): self._PropertyChanged -= handler def __setattr__(self, name, value): object.__setattr__(self, name,value) if name != "_PropertyChanged" and name != "_OnPropertyChanged": if len(self._trackedNames) == 0 or name in self._trackedNames: self._OnPropertyChanged(self, PropertyChangedEventArgs(name)) On Wed, Aug 5, 2009 at 1:50 PM, Steve Apiki < [email protected] > wrote: Hi Dino, Thanks for your quick answer and for making things clear on INotifyPropertyChanged. I'd like to have my own derived classes for this project so I think I'm going to steer clear of ExpandoObject and look into implementing INotifyPropertyChanged. And I tried out your suggestion for #2, creating a new class: class Context(object): def __init__(self): self.person = Person("Alfred") and then assigning a new Person as the person attribute of the context: label.DataContext = a_context def button_click(sender, args): a_context.person = Person("Mathilda") which works (for now) as long as I do the UpdateTarget() and presumably will work as well with implementing INotifyPropertyChanged. Thanks, --Steve ----- Original Message ----- From: "Dino Viehland" < [email protected] > To: "Discussion of IronPython" < [email protected] > Sent: Wednesday, August 5, 2009 4:11:26 PM GMT -05:00 US/Canada Eastern Subject: Re: [IronPython] DataBinding from IronPython Object to WPF Property IronPython doesn't actually support INotifyPropertyChanged - it only supports custom type descriptor so that WPF can get at the values but it doesn't get the change notifications. You could make an instance of ExpandoObject which does support it: import clr clr.AddReference('Microsoft.Scripting.Core') from Microsoft.Dynamic import ExpandoObject a = ExpandoObject() a.name = 'Foo' Or you could implement INotifiyPropertyChanged on the Person object and use a property which fires the event changed notification. My only thought on #2 would be to add another point of indirection. So rather than updating the global a_person update a_person.real_value and have that update fire a bunch of changed events. > -----Original Message----- > From: [email protected] [mailto: users- > [email protected] ] On Behalf Of Steve Apiki > Sent: Wednesday, August 05, 2009 12:58 PM > To: [email protected] > Subject: [IronPython] DataBinding from IronPython Object to WPF > Property > > Hello, > > I'm working with IronPython 2.6 Beta 1. > > I have the following Python class: > > class Person(object): > def __init__(self, name): > self.name = name > > I'd like to be able to bind the name property of an instance of this > class to a WPF textbox control. > > I can do this easily enough either in XAML or in code. When the > application starts, the textbox displays the person's name as expected. > > However, if I make changes to the name, say, in response to a button > click: > > def button_click(sender, args): > a_person.name += ", jr." > > I don't see these changes reflected in the textbox. > > I can make this work by calling UpdateTarget on the binding expression > explicitly: > > exp = BindingOperations.GetBindingExpression(textbox, > TextBox.TextProperty) > exp.UpdateTarget() > > but I had thought this would work without the explicit step, since it > appears that IronPython supports INotifyPropertyChange. > > Two questions: > > (1) Is it possible to get databinding to work this way without having > to explicity UpdateTarget? > > > (2) Say instead of the click handler above, we had: > > def button_click(sender, args): > global a_person > a_person = Person("Fred") > > In this case, the textbox remains bound to the first Person (which is > no longer accessible from Python). Is there any way to get the binding > to re-sync to the new object, short of setting a completely new binding > to Person("Fred") in code? > > > Full example follows. > > Thanks, > > --Steve > > ----------------------------------------- > > import clr > clr.AddReferenceByName("PresentationFramework, Version=3.0.0.0, > Culture=neutral, PublicKeyToken=31bf3856ad364e35") > clr.AddReferenceByName("PresentationCore, Version=3.0.0.0, > Culture=neutral, PublicKeyToken=31bf3856ad364e35") > clr.AddReferenceByPartialName("IronPython") > clr.AddReference("IronPython.Modules") > > from System.Windows import Application, Window > from System.Windows.Controls import StackPanel, Button, TextBox > from System.Windows.Data import Binding, BindingMode, BindingOperations > > class Person(object): > def __init__(self, name): > self.name = name > a_person = Person("Al") > > button = Button() > button.Content = "Test" > > textbox = TextBox() > textbox.DataContext = a_person > binding = Binding("name") > binding.Source = a_person > binding.Mode = BindingMode.OneWay > textbox.SetBinding(TextBox.TextProperty, binding) > > def button_click(sender, args): > """ click handler """ > a_person.name += ", jr." > > # if you uncomment the following, the textbox is updated > # with each button click. If you don't, the text never changes. > #exp = BindingOperations.GetBindingExpression(textbox, > TextBox.TextProperty) > #exp.UpdateTarget() > > button.Click += button_click > > > window = Window() > stackpanel = StackPanel() > stackpanel.Children.Add(button) > stackpanel.Children.Add(textbox) > window.Content = stackpanel > > Application().Run(window) > > > > > > > _______________________________________________ > Users mailing list > [email protected] > http://lists.ironpython.com/listinfo.cgi/users-ironpython.com _______________________________________________ Users mailing list [email protected] http://lists.ironpython.com/listinfo.cgi/users-ironpython.com _______________________________________________ Users mailing list [email protected] http://lists.ironpython.com/listinfo.cgi/users-ironpython.com _______________________________________________ Users mailing list [email protected] http://lists.ironpython.com/listinfo.cgi/users-ironpython.com _______________________________________________ Users mailing list [email protected] http://lists.ironpython.com/listinfo.cgi/users-ironpython.com
