2016-09-21 6 views
0

ich nächstes Modell haben:ListBox binden an ObservableCollection ist nicht mit der Sammlung aktualisiert

public class MyModel 
{ 
    public ObservableCollection<MyObject> MyList {get; set;} 
} 

public class MyObject 
{ 
    MyObservableDictionary MyDictionary {get; set;} 
} 

public class MyObservableDictionary : ObservableCollection<EnymValue> 
{ 
} 

public class EnymValue : INotifyPropertyChanged 
{ 
    private MyEnum key; 
    private string value; 

    public MyEnum Key 
    { 
     get 
     { 
      return this.key; 
     } 
     set 
     { 
      this.key = value; 
      NotifyPropertyChanged("Key"); 
     } 
    } 
    public string Value 
    { 
     get 
     { 
      return this.value; 
     } 
     set 
     { 
      this.value = value; 
      NotifyPropertyChanged("Value"); 
     } 
    } 

    public LanguageValue(MyEnum key, string value) 
    { 
     this.Key = key; 
     this.Value = value; 
    } 

    public event PropertyChangedEventHandler PropertyChanged; 
    public void NotifyPropertyChanged([System.Runtime.CompilerServices.CallerMemberName]string propertyName = "") 
    { 
     if (PropertyChanged != null) 
     { 
      PropertyChanged(this, new PropertyChangedEventArgs(propertyName)); 
     } 
    } 
} 

public enum MyEnum 
{ 
} 

Und Ansicht habe ich eine List-Box:

<ListBox x:Name="MyList" SelectionMode="Single" ItemsSource="{Binding Path=MyList, Mode=OneWay}"> 
    <ListBox.ItemTemplate> 
     <DataTemplate> 
      <TextBlock Text="{Binding Path=MyDictionary, Mode=OneWay, Converter={StaticResource myEnumToTextConverter}}" /> 
     </DataTemplate> 
     </ListBox.ItemTemplate> 
</ListBox> 

(myEnumToTextConverter Wandler wählt nur das erste Element aus der Sammlung und Geben Sie den Wert oder eine bestimmte Konstante zurück, wenn die Sammlung null oder leer ist.

Ich möchte, dass die Listbox meines Modells aktualisiert wird n jeder EnymValue Werte werden geändert. Ist es irgendwie möglich, dies zu implementieren?

Derzeit wird die Ansicht nicht aktualisiert, wenn Value geändert wird. Ich habe versucht, EnymValue von INotifyPropertyChanged zu erben, aber das hat nicht geholfen. Sieht wie PropertyChanged == null auf EnymValue.NotifyPropertyChanged aus, wenn Eigenschaft aktualisiert wird.

+1

Nicht so, wie Sie es tun. Diese "Bindung" wird nicht "INotifyCollectionChanged" abonnieren, da Sie die Auflistung an eine "String" -Eigenschaft binden. Wenn Sie also die Sammlung ändern, wird niemand davon erfahren und die Bindung wird das Ziel nicht aktualisieren. –

Antwort

2

ObservableCollection kann UI über Änderungen benachrichtigen, wenn die Sammlung selbst geändert wird (Elemends werden hinzugefügt oder gelöscht). Aber ObservableCollection ist nicht bekannt, dass Änderungen vorgenommen werden, wenn Sie eines seiner Elemente ändern. Um das Problem zu lösen, können Sie das Ereignis CollectionChange Ereignis einer beobachtbaren Sammlung abonnieren, und wenn ein neues Element hinzugefügt wird, abonnieren Sie PropertyChanged für neue Objekte. Wenn das PropertyChanged-Ereignis ausgelöst wird, können Sie eine Benachrichtigung auf Ihrer Liste auslösen. OnPropertyChanged(()=>MyItems); Sie sollten vorsichtig sein, diese Lösung zu implementieren und sich daran zu erinnern, sich von den Ereignissen abzumelden, um Speicherlecks zu vermeiden.

Ein Beispiel dafür, was ich meine, können Sie in this answer sehen.

+0

@EdPlunkett Ich habe gerade die vorgeschlagene Lösung getestet und es funktioniert wie erwartet. Ich meine OnPropertyChanged ("MyItems") wird nicht ignoriert wie du erwähnt hast. Bei Bedarf kann ich Code zum Nachweis bereitstellen. Warum denkst du, dass es ignoriert werden sollte? – 3615

+0

Ich war mir ziemlich sicher, dass ich das versucht hatte und es hatte nicht funktioniert. Ich habe mich vorher geirrt. –

+0

Habe es einfach getestet und du hast recht, es funktioniert wie du sagst. Danke, dass du mich darauf aufmerksam gemacht hast. –

0

Ihre MyDictionary sollte eine Aktualisierung erzwingen. Der einfachste Weg ist, um seinen alten Wert neu zuweisen und implementieren INPC in MyObject wie unten:

public class MyObject: INotifyPropertyChanged 
    { 
     MyObservableDictionary _myDictionary; 
     public MyObservableDictionary MyDictionary { 
      get 
      { 
       return _myDictionary; 
      } 
      set 
      { 
       _myDictionary = value; 
       OnPropertyChanged("MyDictionary"); 
      } 
     } 

     public MyObject() 
     { 
      MyDictionary = new MyObservableDictionary(); 
     } 

     public event PropertyChangedEventHandler PropertyChanged; 
     public void OnPropertyChanged(string prop) 
     { 
      if (PropertyChanged != null) 
       PropertyChanged(this, new PropertyChangedEventArgs(prop)); 
     } 
    } 

Beispielcode zum Wert zu ändern:

private void Button_Click(object sender, RoutedEventArgs e) 
{ 
    // vm is ViewModel instance, vm is DataContext set for Window 

    var old = vm.MyList[0].MyDictionary; 
    vm.MyList[0].MyDictionary[0].Value = "aaaa"; 
    vm.MyList[0].MyDictionary = old; 
} 

Getestet habe ich diese, und es zeigt geänderten Wert als " aaaa ".

Verwandte Themen