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@lists.ironpython.com
http://lists.ironpython.com/listinfo.cgi/users-ironpython.com

Reply via email to