Oops -- I should have pointed out that pyevent.py is in the standard IronPython distribution; probably in a directory called "samples" or "tutorial". (Network service in the bus is flaky, so I'm finding it hard to check.)
On Wed, Aug 5, 2009 at 5:35 PM, Curt Hagenlocher <[email protected]>wrote: > 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
