Laden...

[erledigt] WPF, Databinding einer Liste (ObservableCollection) zu einer Listbox

Erstellt von adeptus vor 11 Jahren Letzter Beitrag vor 11 Jahren 9.223 Views
adeptus Themenstarter:in
106 Beiträge seit 2011
vor 11 Jahren
[erledigt] WPF, Databinding einer Liste (ObservableCollection) zu einer Listbox

Hi,

ich habe eine Klasse die eine Liste von Items verwaltet

ObservableCollection <Item> objListe;

Diese wird als DataContext einer ListBox übergeben.

ListBox.DataContext = objListe;

Damit sehe ich zur Laufzeit wunderbar meine Einträge in der ListBox. Füge ich per Button ein paar Einträge meiner Liste hinzu erscheinen sie auch brav in der ListBox.

Was nicht funktioniert ist, das Update der Listbox wenn ich einen der Items direkt ändere. Ich füge also nichts der Liste hinzu sondern ändere eines ihrer Elemente in dem ich zB eine Eigenschaft des 2. Items ändere

objListe[1].Eigenschaft = "Neuer Wert";

Diese Änderungen werden nicht in der ListBox reflektiert.

Meine Items implementieren auch brav INotifyPropertyChanged, so daß andere Controls durchaus die Änderung anzeigen

Durch setzen von DataContext auf null, und anschliessendem erneutem anbinden auf objListe

ListBox.DataContext = null; ListBox.DataContext = objListe

werden die Änderungen natürlich sichtbar, doch es muß doch auch anders gehen...

Hat jemand eine Idee?

Vielen Dank im Vorraus! 👍

It's not a bug, it always worked that way!
Codegrunts
XING

1.552 Beiträge seit 2010
vor 11 Jahren

Hallo adeptus,

erbt dein Objekt von INotifyPropertyChanged?

Gruß,
Michael

Mein Blog
Meine WPF-Druckbibliothek: auf Wordpress, myCSharp

adeptus Themenstarter:in
106 Beiträge seit 2011
vor 11 Jahren

Hi Michael,

sowohl die Items als auch die Liste implementieren INotifyPropertyChanged, ja.

It's not a bug, it always worked that way!
Codegrunts
XING

114 Beiträge seit 2009
vor 11 Jahren

Soweit ich weiß (und ich bin immer ein bisschen unsicher mit Binding) musst du nach dem Ändern der Property in deiner Item-Klasse den PropertyChanged aufrufen. Das implementieren der Schnittstelle reicht da nicht.


        public string PhoneNumber
        {
            get
            {
                return this.phoneNumberValue;
            }

            set
            {
                if (value != this.phoneNumberValue)
                {
                    this.phoneNumberValue = value;
                    NotifyPropertyChanged();
                }
            }
        }

Auszug aus dem entsprechenden Beispiel aus dem MSDN.

adeptus Themenstarter:in
106 Beiträge seit 2011
vor 11 Jahren

Hi,

ja klar, das mache ich ja auch. Ich habe ja auch ein paar Labels und Textfelder die auch brav auf die Änderungen reagieren.

Nur die Listbox zeigt dann noch immer die Werte der Items VOR der Änderung...

It's not a bug, it always worked that way!
Codegrunts
XING

1.552 Beiträge seit 2010
vor 11 Jahren

Wie sieht dein Binding in der ListBox aus? Hast du etwas an dem Mode umgestellt? Sprich, OneTime, ect.

Mein Blog
Meine WPF-Druckbibliothek: auf Wordpress, myCSharp

adeptus Themenstarter:in
106 Beiträge seit 2011
vor 11 Jahren

Hier ein Ausschnitt aus dem XAML:

<StackPanel Name="pnlListe" Grid.Row ="2" Orientation="Horizontal" >
    <ListBox ItemsSource="{Binding}"  Height="100" HorizontalAlignment="Left" Name="listBox1" VerticalAlignment="Top" Width="283" SelectedIndex="{Binding Path=Selected}" />
...
</StackPanel>

Die ListBox ist in einem StackPanel dessen DataContext ich zur Laufzeit auf C# heraus auf objListe setze

pnlListe.DataContext = objKundenListe;

Und hier die Listenklasse:


    class Kunden : ObservableCollection<Kunde>, INotifyPropertyChanged
    {
        private int iSelected = 0;

        void Alter_Vorname(int iIndex, string sNewValue)
        {
            this[iIndex].Vorname = sNewValue;
        }

        public int Selected
        {
            get
            {
                return this.iSelected;
            }
            set
            {
                this.iSelected = value;
                OnPropertyChanged(new PropertyChangedEventArgs("Selected"));
                OnPropertyChanged(new PropertyChangedEventArgs("SelectedKunde"));
            }

        }

        public Kunde SelectedKunde
        {
            get
            {
                return this.Items[this.iSelected];
            }
        }
    }

Die Methode Alter_Vorname (2, "Pascal") wird dann per Knopfdruck aufgerufen. Damit bekommt der dritte Kunde in der Liste den Vornamen "Pascal". Das klappt ja auch denn andere Controls auf dem Fenster, welche per Binding mit der Eigenschaft "SelectedKunde" verbunden sind, zeigen den korrekten Vornamen wenn der dritte Kunde in der Liste markiert wird.

It's not a bug, it always worked that way!
Codegrunts
XING

1.552 Beiträge seit 2010
vor 11 Jahren

Hast du in der ListBox auch ein ItemTemplate, denn sonst wird ToSting() aufgerufen, und ich denke nicht dass das dies bei NotifyPropertyChanged updated.

Mein Blog
Meine WPF-Druckbibliothek: auf Wordpress, myCSharp

adeptus Themenstarter:in
106 Beiträge seit 2011
vor 11 Jahren

DAS WAR'S!!!!

In der Tat hatte ich bisher kein DataTemplate für die ListBox gemacht und nur meiner Kunden-Klasse ein eigenes ToString() spendiert.

Es muß tatsächlich immer auf eine Eigenschaft gebunden werden um eine Two-Way-Bindung erstellen zu können. Und wieder ein genieler AHA-Effekt!

Danke! 👍

It's not a bug, it always worked that way!
Codegrunts
XING