wpf binding listbox ironpython

wpf - ¿Cómo me ligo a un ListBox en IronPython?



binding (3)

IronPython distingue entre mayúsculas y minúsculas y no utiliza la palabra clave new . Tratar:

MyListBox.ItemsSource = ObservableCollection[Email]()

Estoy empezando a usar IronPython con WPF y no entiendo cómo se supone que se debe realizar el enlace.

Normalmente en WPF solo haría algo como esto:

<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>

Luego en mi código detrás:

MyListBox.ItemsSource = new ObservableCollection<Email>()

Pero en IronPython no podemos tener una ObservableCollection de objetos, solo tipos. Esto no funciona:

MyListBox.ItemsSource = new ObservableCollection[email]()

Como arroja la excepción: "Array esperado [Type], got classobj"

¿Que se supone que haga? ¡Ayuda por favor!


Lo resolví yo mismo, tenía algunas cosas malas y me faltaban algunos puntos clave también. Espero que esta respuesta pueda ayudar a alguien más.

Lo primero era que necesita pyevent.py desde el tutorial / directorio en su directorio de IronPython.

Segundo, necesitamos una clase de ayuda:

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))

Entonces necesitas declarar tu clase de datos así:

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")

Finalmente establezca ItemSource de ListBox:

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

Acceda a este enlace para obtener ayuda: http://palepoli.skr.jp/wp/2009/06/28/wpf-listview-databinding-for-ironpython/


Ampliando en la respuesta de Boden, es posible que desee mejorar un poco la NotifyPropertyChangedBase:

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)) def init_view(self, view): xaml = view self.view = XamlLoader(xaml).Root self.view.DataContext = self def declareNotifiable(self, *symbols): for symbol in symbols: self.defineNotifiableProperty(symbol) def defineNotifiableProperty(self, symbol): dnp = """ import sys sys.path.append(__file__) from NotifyProperty import * @notify_property def {0}(self): return self._{0} @{0}.setter def {0}(self, value): self._{0} = value """.format(symbol) d = globals() exec dnp.strip() in d setattr(self.__class__, symbol, d[symbol]) exec("self.{0} = ''''".format(symbol))

Con ese conjunto, podrías hacer algo como:

class Email(NotifyPropertyChangedBase): def __init__(self): self.defineNotifiableProperty("From", "Subject")

Con eso en su lugar, obtendrá los elementos @notify_property y @ property.setter establecidos para todo en la llamada defineNotifiableProperty.