[Python.NET] How to handle INotifyPropertyChanged interface

Tony Roberts tony at pyxll.com
Sun Apr 3 11:20:47 EDT 2016


What's the full stack trace?

I suspect it's something to do with the event declared on the interface not
being implemented. The managed type constructed doesn't define any events,
so that would cause the construction of the type of fail - which is
probably the error you're getting (although without the stack trace it's
just an educated guess).

It shouldn't be too hard to add events to the derived type if someone
wanted to have a go at implementing it. The code is in the
CreateDerivedType method in src/runtime/classderived.cs. To be consistent
with how methods and properties work, it would need a clrevent function
adding to the clr module (src/runtime/resource/clr.py) - maybe it could
work like this:

class MyClass(INotifyPropertyChanged):
    OnPropertyChanged = clr.clrevent(event_attributes, event_type)

Then in classderived.cs the class any clrevents on the python class could
be added to the managed type using TypeBuilder.DefineEvent.

So, anyway - short answer is that what you're trying to do won't work
without changes to pythonnet; but the changes required shouldn't be too
hard if you wanted to have a go.

Best regards,
Tony


On Sun, Apr 3, 2016 at 3:37 PM Hansong Huang <hhspiny at live.com> wrote:

> It seems inheriting from INotifyPropertyChanged is the cause
>
> self.window = System.Windows.Markup.XamlReader.Load(outStream)
> self.window.DataContext = MyViewModel()
> class MyViewModel(System.Object):
>     __namespace__ = "WPFPyDemo"
>     def __init__(self):
>         super(MyViewModel,self).__init__()
>         self._inputText = "Line - in"
>     @clr.clrproperty(str)
>     def inputText(self):
>         return self._inputText
>     @inputText.setter
>     def inputText(self,value):
>         self._inputText = value
>         self.OnPropertyChanged("inputText")
>
> The above code works fine.
>
> but if switch inheritance to
> class MyViewModel(System.ComponentModel.INotifyPropertyChanged):
> and nothing else changed, python gives
>
> "The process terminates due to StackOverflowException"
>
> Not sure why.
>
>
> Thanks for the help
>
> ------------------------------
> From: hhspiny at live.com
> To: pythondotnet at python.org
> Subject: How to handle INotifyPropertyChanged interface
> Date: Thu, 31 Mar 2016 20:38:38 -0400
>
>
> I am still trying to figure out how to implement WPF MVVM with Python.Net.
> Previously, I have successfully used System.Dynamic.ExpandoObject as a
> ViewModel container
>
> self.window = System.Windows.Markup.XamlReader.Load(outStream)
> self.window.DataContext = DotNetExpandoObject()
>
> where DotNetExpandoObject is a wrapper class for
> System.Dynamic.ExpandoObject
> class DotNetExpandoObject(System.Dynamic.ExpandoObject):
> ...  in which I redefined __getattr__ and __setattr__
>
> it works flawlessly as System.Dynamic.ExpandoObject implements
> INotifyPropertyChange interface already
>
> Now, I would like to get away from using System.Dynamic.ExpandoObject but
> to implement my own
>
> I first tried to expose a python class back to .Net
> class MyViewModel(System.Object):
>     __namespace__ = "WPFPyDemo"
>     def __init__(self):
>         super(MyViewModel,self).__init__()
>         self._inputText = "Line - in"
>     @clr.clrproperty(str)
>     def inputText(self):
>         return self._inputText
>     @inputText.setter
>     def inputText(self,value):
>         self._inputText = value
>         self.OnPropertyChanged("inputText")
>
> self.window.DataContext = MyViewModel()
>
> The one direction data binding works fine, and the "Line - in" text
> correctly shows up in the textblock control.
> obviously this is not sufficient as there is no INotifyPropertyChange
> interface.
>
> So, I inherit the interface , and tries to implement the typical C# code
> " public event PropertyChangedEventHandler PropertyChanged"
>
> -- not sure how to handle event in Python.Net, the follow code probably is
> completely wrong
>
> class ViewModel(System.ComponentModel.INotifyPropertyChanged):
>     __namespace__ = "WPFPy"
>     def __init__(self):
>         super(ViewModel, self).__init__()
>         self.PropertyChanged =
> System.ComponentModel.PropertyChangedEventHandler
>     def OnPropertyChanged(self, propertyName):
>         if self.PropertyChanged != None:
>             PropertyChanged(self,
> System.ComponentModel.PropertyChangedEventArgs(propertyName))
>
> class MyViewModel(ViewModel):
>     __namespace__ = "WPFPyDemo"
>     def __init__(self):
>         super(MyViewModel,self).__init__()
>         self._inputText = "Line - in"
>
>     @clr.clrproperty(str)
>     def inputText(self):
>         return self._inputText
>     @inputText.setter
>     def inputText(self,value):
>         self._inputText = value
>         self.OnPropertyChanged("inputText")
>
>
> The process terminates due to StackOverflowException.
> Looks like the error happens when WFP recoganized INotifyPropertyChange
> interface and tries to access MyViewModel class via it.
> _________________________________________________
> Python.NET mailing list - PythonDotNet at python.org
> https://mail.python.org/mailman/listinfo/pythondotnet
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.python.org/pipermail/pythondotnet/attachments/20160403/34c1cf97/attachment-0001.html>


More information about the PythonDotNet mailing list