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 classclass 
ViewModelBase(System.ComponentModel.INotifyPropertyChanged):  where 
PropertyChanged, add_PropertyChanged, remove_PropertyChanged are 
implementedthenclass 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, Systemclass 
DotNetINotifyPropertyChanged(System.ComponentModel.INotifyPropertyChanged):    
__namespace__ = "DotNetINotifyPropertyChanged"    def __init__(self):        
super(DotNetINotifyPropertyChanged, self).__init__()        def 
add_PropertyChanged(self, value):        pass    def 
remove_PropertyChanged(self, value):        
passc1=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 present1. the 
class is derived from INotifyPropertyChanged interface2. 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 .Netclass 
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

Reply via email to