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