Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How do I bind to a ListBox in IronPython?

I am just starting out using IronPython with WPF and I don't quiet understand how binding is supposed to be done.

Normally in WPF I would just do something like this:

<ListBox Name="MyListBox">
    <ListBox.Resources>
        <Style TargetType="ListBoxItem">
            <Setter Property="ContentTemplate">
                <Setter.Value>
                    <DataTemplate>
                        <DockPanel>
                            <TextBlock Text="{Binding Path=From}" />
                            <TextBlock Text="{Binding Path=Subject}" />
                        </DockPanel>
                     </DataTemplate>
                </Setter.Value>
            </Setter>
        </Style>
    </ListBox.Resources>
</ListBox>

Then in my code behind:

MyListBox.ItemsSource = new ObservableCollection<Email>()

But in IronPython we cannot have an ObservableCollection of objects, only types. This does not work:

MyListBox.ItemsSource = new ObservableCollection[email]()

As it throws the Exception: "expected Array[Type], got classobj"

What am I supposed to do? Help please!

like image 274
Boden Garman Avatar asked Jan 19 '23 14:01

Boden Garman


1 Answers

I worked this out myself, I had a few things wrong and was missing a few key point as well. I hope this answer can help someone else.

First was that you need pyevent.py from the tutorial/ directory in your IronPython directory.

Second we need a helper class:

class NotifyPropertyChangedBase(INotifyPropertyChanged):
    """INotifyProperty Helper"""
    PropertyChanged = None
    def __init__(self):
        (self.PropertyChanged, self._propertyChangedCaller) = make_event()

    def add_PropertyChanged(self, value):
        self.PropertyChanged += value

    def remove_PropertyChanged(self, value):
        self.PropertyChanged -= value

    def OnPropertyChanged(self, propertyName):
        self._propertyChangedCaller(self, PropertyChangedEventArgs(propertyName))

Then you need to declare your data class like so:

class Email(NotifyPropertyChangedBase):
    """
        use setter getter.
        IronPython 2.6 or later.
    """
    @property
    def From(self):
        return self._From

    @From.setter
    def From(self, value):
        self._From = value
        self.OnPropertyChanged("From")

    @property
    def Subject(self):
        return self._Subject

    @Subject.setter
    def Subject(self, value):
        self._Subject = value
        self.OnPropertyChanged("Subject")

Finally set the ListBox's ItemSource:

self.data = ObservableCollection[Email]()
self.MyListBox.ItemsSource = self.data

Credit to this link for the help: http://palepoli.skr.jp/wp/2009/06/28/wpf-listview-databinding-for-ironpython/

like image 114
Boden Garman Avatar answered Feb 12 '23 07:02

Boden Garman