I think this is related to another issue that I'm experiencing:

https://github.com/pythonnet/pythonnet/issues/148

In your case I was very interested what is difference between 2 calls
to add_PropertyChanged
and uploaded a notebook showing the difference:

https://gist.github.com/denfromufa/8ef691ca571b736278d751b1b256e814

Note that from console the results are hard crashes!

I'm using the current development branch.

::## this is with interface

python MVVM.py
['__call__', '__class__', '__cmp__', '__delattr__', '__doc__',
'__format__', '__
func__', '__get__', '__getattribute__', '__hash__', '__init__', '__new__',
'__re
duce__', '__reduce_ex__', '__repr__', '__self__', '__setattr__',
'__sizeof__', '
__str__', '__subclasshook__', 'im_class', 'im_func', 'im_self']
success: text
['__call__', '__class__', '__delattr__', '__delete__', '__doc__',
'__format__',
'__getattribute__', '__getitem__', '__hash__', '__init__', '__module__',
'__new_
_', '__reduce__', '__reduce_ex__', '__repr__', '__set__', '__setattr__',
'__size
of__', '__str__', '__subclasshook__']
Traceback (most recent call last):
  File "MVVM.py", line 57, in <module>
    a1.add_PropertyChanged("text")
TypeError: No method matches given arguments

Unhandled Exception: System.InvalidOperationException: Handle is not
initialized
.
   at System.Runtime.InteropServices.GCHandle.Free()
   at Python.Runtime.PythonDerivedType.Finalize(IPythonDerivedType obj)
   at A.A.Finalize()

::## this is with System.Object

python MVVM.py
['__call__', '__class__', '__cmp__', '__delattr__', '__doc__',
'__format__', '__
func__', '__get__', '__getattribute__', '__hash__', '__init__', '__new__',
'__re
duce__', '__reduce_ex__', '__repr__', '__self__', '__setattr__',
'__sizeof__', '
__str__', '__subclasshook__', 'im_class', 'im_func', 'im_self']
success: text
['__call__', '__class__', '__cmp__', '__delattr__', '__doc__',
'__format__', '__
func__', '__get__', '__getattribute__', '__hash__', '__init__', '__new__',
'__re
duce__', '__reduce_ex__', '__repr__', '__self__', '__setattr__',
'__sizeof__', '
__str__', '__subclasshook__', 'im_class', 'im_func', 'im_self']
success: text

Unhandled Exception: System.InvalidOperationException: Handle is not
initialized
.
   at System.Runtime.InteropServices.GCHandle.Free()
   at Python.Runtime.PythonDerivedType.Finalize(IPythonDerivedType obj)
   at A.A.Finalize()









On Mon, Apr 4, 2016 at 8:47 PM, Hansong Huang <hhsp...@live.com> wrote:

> New update:
>
> I found why the stackoverflow happened, and how to avoid it and make MVVM
> model work. however, it did not entirely solve the problem.
>
> The StackOverFlow was not directly because of the INotifyPropertyChanged
> interface, but because I used a class derived from it.
>
> if I define my ViewModel as
>
> class ViewModel(System.ComponentModel.INotifyPropertyChanged):
> and implement all components such as clr.clrproperty, PropertyChanged,
> add_PropertyChanged, remove_PropertyChanged etc as previous posted, and
> assign this class to window.DataContext, everything actually worked.
>
> The problem is that I used a derived class
> class ViewModelBase(System.ComponentModel.INotifyPropertyChanged):  where 
> PropertyChanged,
> add_PropertyChanged, remove_PropertyChanged are implemented
> then
> class ViewModel(ViewModelBase):  where clr.clrproperty is implemented.
> This results in the StackOverflow....
>
> To make a simpler case, I tested out the following code that is entirely
> self-contained.
>
> import clr, System
> class
> DotNetINotifyPropertyChanged(System.ComponentModel.INotifyPropertyChanged):
>     __namespace__ = "DotNetINotifyPropertyChanged"
>     def __init__(self):
>         super(DotNetINotifyPropertyChanged, self).__init__()
>     def add_PropertyChanged(self, value):
>         pass
>     def remove_PropertyChanged(self, value):
>         pass
> c1=DotNetINotifyPropertyChanged()
> c1.add_PropertyChanged("text")
> print "C1 success"
>
> class A(DotNetINotifyPropertyChanged):
>     __namespace__ = "A"
>     def __init__(self):
>         super(A,self).__init__()
> a1 = A()
> a1.add_PropertyChanged("text")
> print "a1 success"
>
> if you run it,  you can see that "C1 success" is printed, but python can
> not find a1.add_PropertyChanged method and throws exception. which I
> believe is the direct cause of StackOverflow above.
>
> Obviously, if DotNetINotifyPropertyChanged is derived from "object", the
> above code runs fine.
>
> Therefore the question is, what is it that inheriting from .NET interface
> that is unique, that the method defined in base class is not inherited by
> child class?
>
> Hansong
>
>
>
> ------------------------------
> From: t...@pyxll.com
> Date: Sun, 3 Apr 2016 15:40:17 +0000
> Subject: Re: [Python.NET] How to handle INotifyPropertyChanged interface
> To: hhsp...@pine.cc; pythondotnet@python.org
>
> Yeah, it looks like the crash is probably because of the missing event
> implementation as suspected. I'm a bit surprised that it didn't fail
> earlier when trying to instantiate the type.
>
> If you do get a chance to take a look at adding that functionality be sure
> to submit a pull request!
>
> Best regards,
> Tony
>
>
> On Sun, Apr 3, 2016 at 4:30 PM Hansong Huang <hhsp...@live.com> wrote:
>
> Tony,
>
> thanks for the hint.
>
> the event PropertyChanged was declared in INotifyPropertyChanged interface
> by pythonnet, but obviously not implemented.
> [('PropertyChanged', <unbound event 'PropertyChanged'>),
>
> anyway, the stackoverflow only happens if both following are present
> 1. the class is derived from INotifyPropertyChanged interface
> 2. the class exposes property back to .Net vis @clrproperty
>
> which seems to prove that it is the PropertyChanged event that is not
> implemented in python class resulted in the crash.
>
> I was not sure if .Net event can be handled by pythonnet. I found a few
> examples with IronPython, but there, a python class of "event" seems to be
> implemented instead.
>
> Below is the stack trace
>
>
>   [External Code]
>   clr.dll!CallDescrWorkerInternal () Unknown
>   clr.dll!CallDescrWorkerWithHandler(struct CallDescrData *,int) Unknown
>   clr.dll!CallDescrWorkerReflectionWrapper(struct CallDescrData *,class
> Frame *) Unknown
>   clr.dll!RuntimeMethodHandle::InvokeMethod(class Object *,class PtrArray
> *,class SignatureNative *,bool) Unknown
>   mscorlib.ni.dll!00007fffb86e1ca4() Unknown
>   mscorlib.ni.dll!00007fffb8618272() Unknown
>   mscorlib.ni.dll!00007fffb867fc4a() Unknown
>   [External Code]
>   mscorlib.ni.dll!00007fffb86dbaf5() Unknown
>   mscorlib.ni.dll!00007fffb86d281f() Unknown
>   System.ni.dll!00007fffb77556d4() Unknown
>   System.ni.dll!00007fffb7755637() Unknown
>   System.ni.dll!00007fffb775541d() Unknown
>   PresentationFramework.ni.dll!00007fff96c1ca70() Unknown
>   PresentationFramework.ni.dll!00007fff96c23902() Unknown
>   PresentationFramework.ni.dll!00007fff96c22ea1() Unknown
>   PresentationFramework.ni.dll!00007fff96c22693() Unknown
>   PresentationFramework.ni.dll!00007fff96c223c9() Unknown
>   PresentationFramework.ni.dll!00007fff96c21a03() Unknown
>   PresentationFramework.ni.dll!00007fff96c0d84c() Unknown
>   PresentationFramework.ni.dll!00007fff96b97299() Unknown
>   PresentationFramework.ni.dll!00007fff96b9720e() Unknown
>   PresentationFramework.ni.dll!00007fff96c852f0() Unknown
>   WindowsBase.ni.dll!00007fff9f6f9bc9() Unknown
>   WindowsBase.ni.dll!00007fff9f6f9ac6() Unknown
>   WindowsBase.ni.dll!00007fff9f6fca2b() Unknown
>   mscorlib.ni.dll!00007fffb86ca79e() Unknown
>   mscorlib.ni.dll!00007fffb86ca637() Unknown
>   mscorlib.ni.dll!00007fffb86ca5f2() Unknown
>   WindowsBase.ni.dll!00007fff9f913810() Unknown
>   WindowsBase.ni.dll!00007fff9f6fc784() Unknown
>   WindowsBase.ni.dll!00007fff9f6f7c24() Unknown
>   WindowsBase.ni.dll!00007fff9f6f8061() Unknown
>   WindowsBase.ni.dll!00007fff9f6f9e53() Unknown
>   WindowsBase.ni.dll!00007fff9f6f9d82() Unknown
>   WindowsBase.ni.dll!00007fff9f6f9bc9() Unknown
>   WindowsBase.ni.dll!00007fff9f6f9ac6() Unknown
>   WindowsBase.ni.dll!00007fff9f6f7583() Unknown
>   WindowsBase.ni.dll!00007fff9f6f94ff() Unknown
>   WindowsBase.ni.dll!00007fff9f8c496a() Unknown
>   clr.dll!UMThunkStub () Unknown
>   user32.dll!UserCallWinProcCheckWow() Unknown
>   user32.dll!DispatchMessageWorker() Unknown
>   WindowsBase.ni.dll!00007fff9f730ee8() Unknown
>   WindowsBase.ni.dll!00007fff9f70d8fc() Unknown
>   PresentationFramework.ni.dll!00007fff96af98b3() Unknown
>   PresentationFramework.ni.dll!00007fff96af969d() Unknown
>   clr.dll!CallDescrWorkerInternal () Unknown
>   clr.dll!CallDescrWorkerWithHandler(struct CallDescrData *,int) Unknown
>   clr.dll!CallDescrWorkerReflectionWrapper(struct CallDescrData *,class
> Frame *) Unknown
>   clr.dll!RuntimeMethodHandle::InvokeMethod(class Object *,class PtrArray
> *,class SignatureNative *,bool) Unknown
>   mscorlib.ni.dll!00007fffb86e1c20() Unknown
>   mscorlib.ni.dll!00007fffb8618272() Unknown
>   [External Code]
>   clr.dll!UMThunkStub () Unknown
>   [External Code]
> > WPFPy.py!threadStart Line 256 Python
>   [External Code]
>
>
> ------------------------------
> From: t...@pyxll.com
> Date: Sun, 3 Apr 2016 15:20:47 +0000
> Subject: Re: [Python.NET] How to handle INotifyPropertyChanged interface
> To: hhsp...@pine.cc; pythondotnet@python.org
>
>
> 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 <hhsp...@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: hhsp...@live.com
> To: pythondotnet@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@python.org
> https://mail.python.org/mailman/listinfo/pythondotnet
>
>
> _________________________________________________
> Python.NET mailing list - PythonDotNet@python.org
> https://mail.python.org/mailman/listinfo/pythondotnet
>
_________________________________________________
Python.NET mailing list - PythonDotNet@python.org
https://mail.python.org/mailman/listinfo/pythondotnet

Reply via email to