[IronPython] IronPython 2.6.1, NET 2.0 and binding cause NullReferenceException

Lukas Cenovsky cenovsky at bakalari.cz
Fri Sep 3 17:10:31 CEST 2010


  I've found a workaround for this issue. When I was porting this code 
to Silverlight, I could not use default view because Silverlight does 
not have it. So I created my own CollectionViewSource and bind it to the 
listbox. It works. Then I tried it in WPF and it works there too.

So the problem below is caused by default views that WPF create 
automatically when you bind a collection.

--
-- Lukáš


On 2.9.2010 12:32, Lukas Cenovsky wrote:
> Hi all,
> I've found a bug in IronPython 2.6.1 that causes to terminate 
> IronPython 2.6.1 based on .NET 2.0 with SystemError: Object reference 
> not set to an instance of an object. exception.
>
> Below is the code. You need clrtype.py and pyevent.py to run it. When 
> you run it, a simple form with listbox and checkbox appears. The SK 
> items in the listbox can be filtered out by checking the checkbox. 
> There is a binding to the selected item in the listbox which is the 
> cause of the error. If you select the SK item and check the checkbox 
> to filter it out, the exception occurs. But it only occurs in 
> IronPython based on .NET 2.0 - it works fine in IronPython 2.6.1 based 
> on .NET 4.
>
> Here is the full exception:
>
> C:\BindingTest>C:\IronPython-2.6.1.NET20\ipy.exe -X:Debug 
> -X:ShowClrExceptions BindingTest.py
> Traceback (most recent call last):
>   File "BindingTest.py", line 133, in <module>
>   File "BindingTest.py", line 125, in filtered
> SystemError: Object reference not set to an instance of an object.
> CLR Exception:
>     NullReferenceException
> :
> Object reference not set to an instance of an object.
>
> I'm going to build IronPython in the debug mode this afternoon to see 
> what's wrong inside and possible fix it in my own build.
>
> As this is quite showstopper for me, I would be very happy if somebody 
> can help me with this. Thank you.
>
> --
> -- Lukáš
>
> --- file BindingTest.py ---
>
> import clr
> import clrtype
> import pyevent
> clr.AddReference('WindowsBase')
> clr.AddReference('PresentationFramework')
> from System.Windows import Application
> from System.ComponentModel import INotifyPropertyChanged, 
> PropertyChangedEventArgs
> from System.Collections.ObjectModel import ObservableCollection
> from System.Windows.Markup import XamlReader
> from System.Windows.Data import CollectionViewSource
>
> xaml = """<Window 
> xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
>   xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
>   Title="Binding test" Height="150" Width="250">
> <Grid x:Name="root">
> <Grid.RowDefinitions>
> <RowDefinition Height="Auto" />
> <RowDefinition Height="*" />
> <RowDefinition Height="Auto" />
> </Grid.RowDefinitions>
> <CheckBox Content="Filtered" IsChecked="{Binding filtered}" />
> <ListBox Name="lbxMountains" Grid.Row="1"
>               ItemsSource="{Binding lstMountains}"
>               SelectedItem="{Binding selMountain}">
> <ListBox.ItemTemplate>
> <DataTemplate>
> <StackPanel Orientation="Horizontal">
> <TextBlock Grid.Column="1" Text="{Binding country}" />
> <TextBlock Text=": " />
> <TextBlock Text="{Binding name}" />
> </StackPanel>
> </DataTemplate>
> </ListBox.ItemTemplate>
> </ListBox>
> <TextBlock Grid.Row="2" Text="{Binding selMountain.name}" />
> </Grid>
> </Window>"""
>
> class NotifyPropertyChangedBase(INotifyPropertyChanged):
>     PropertyChanged = None
>
>     def __init__(self):
>         self.PropertyChanged, self._propertyChangedCaller = 
> pyevent.make_event()
>
>     def add_PropertyChanged(self, value):
>         self.PropertyChanged += value
>
>     def remove_PropertyChanged(self, value):
>         self.PropertyChanged -= value
>
>     def OnPropertyChanged(self, propertyName):
>         if self.PropertyChanged is not None:
>             self._propertyChangedCaller(self, 
> PropertyChangedEventArgs(propertyName))
>
> class Mountain(NotifyPropertyChangedBase):
>     __metaclass__ = clrtype.ClrClass
>
>     def __init__(self, name, country):
>         super(Mountain, self).__init__()
>         self.name = name
>         self.country = country
>
>     @property
>     def name(self):
>         return self._name
>
>     @name.setter
>     def name(self, value):
>         self._name = value
>         self.OnPropertyChanged('name')
>
>     @property
>     def country(self):
>         return self._country
>
>     @country.setter
>     def country(self, value):
>         self._country = value
>         self.OnPropertyChanged('country')
>
> class Mountains(NotifyPropertyChangedBase):
>     __metaclass__ = clrtype.ClrClass
>
>     def __init__(self):
>         super(Mountains, self).__init__()
>         self._lstMountains = ObservableCollection[Mountain]()
>         self.lstMountains.Add(Mountain('Snezka', 'CR'))
>         self.lstMountains.Add(Mountain('Rip', 'CR'))
>         self.lstMountains.Add(Mountain('Gerlach', 'SK'))
>         self.filtered = False
>         self.selMountain = Mountain('', '')
>
>     @property
>     @clrtype.accepts()
>     @clrtype.returns(Mountain)
>     def selMountain(self):
>         return self._selMountain
>
>     @selMountain.setter
>     @clrtype.accepts(Mountain)
>     @clrtype.returns()
>     def selMountain(self, value):
>         self._selMountain = value
>         self.OnPropertyChanged('selMountain')
>
>     @property
>     @clrtype.accepts()
>     @clrtype.returns(ObservableCollection[Mountain])
>     def lstMountains(self):
>         return self._lstMountains
>
>     @property
>     @clrtype.accepts()
>     @clrtype.returns(bool)
>     def filtered(self):
>         return self._filtered
>
>     @filtered.setter
>     @clrtype.accepts(bool)
>     @clrtype.returns()
>     def filtered(self, value):
>         self._filtered = value
>         self.OnPropertyChanged('filtered')
>         dv = CollectionViewSource.GetDefaultView(self.lstMountains)
>         dv.Filter = (lambda x: x.country == 'CR' if value else True)
>
> class MyApp:
>     def __init__(self):
>         self.root = XamlReader.Parse(xaml)
>         self.root.DataContext = Mountains()
>
> app = Application()
> app.Run(MyApp().root)
>
>
> _______________________________________________
> Users mailing list
> Users at lists.ironpython.com
> http://lists.ironpython.com/listinfo.cgi/users-ironpython.com

-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.python.org/pipermail/ironpython-users/attachments/20100903/6293c15f/attachment.html>


More information about the Ironpython-users mailing list