2016-04-12 10 views
0

Ich versuche einfach Bindung zu tun, um einen Konverter Anzahl der Elemente innerhalb beobachtbaren Sammlung anzuzeigen, die Enum gegeben zu erfüllen, lassen Sie uns ABC D. sagenC# WPF MVVM nicht verbindlich Aktualisierung

Der folgende Code funktioniert, wenn ich es testen mit meinem anderen Projekt, aber auf der einfachsten Projektbindung wird nicht aktualisiert. Der exakt gleiche Code funktioniert in anderen Projekten (wirklich seltsam).

Wie mache ich die Bindung

<Label Content="{Binding Source={x:Static viewmodels:TestViewModel.Instance}, Path=TestModels, Converter={StaticResource TestConverter}, Mode=OneWay}"></Label> 

Converter

class TestConverter : IValueConverter 
{ 
    public object Convert(
     object value, 
     Type targetType, 
     object parameter, 
     CultureInfo culture) 
    { 
     if (value == null) 
      return 0; 
     var v = (ObservableCollection<TestModel>)value; 
     return $"{v.Count}/{v.AsParallel().Count(x => x.TestEnum == TestEnum.A)}/{v.AsParallel().Count(x => x.TestEnum == TestEnum.B)}/{v.AsParallel().Count(x => x.TestEnum == TestEnum.C)}/{v.AsParallel().Count(x => x.TestEnum == TestEnum.D)}"; 
    } 

    public object ConvertBack(
     object value, 
     Type targetType, 
     object parameter, 
     CultureInfo culture) 
    { 
     throw new NotImplementedException(); 
    } 
} 

Modell

public enum TestEnum { A, B, C, D } 

public class TestModel:INotifyPropertyChanged 
{ 
    public event PropertyChangedEventHandler PropertyChanged; 

    private TestEnum _testEnum; 

    public TestModel() 
    { 
     TestEnum = (TestEnum)(TestViewModel.Instance.rnd.Next(0,3)); 

    } 

    public TestEnum TestEnum 
    { 
     get 
     { 
      return _testEnum; 

     } 
     set 
     { 
      _testEnum = value; 
      PropertyChanged?.Invoke(this,new PropertyChangedEventArgs(null)); 
     } 
    } 
} 

Ansichtsmodell

public class TestViewModel : INotifyPropertyChanged 
{ 
    public event PropertyChangedEventHandler PropertyChanged; 

    private static readonly TestViewModel _instance = new TestViewModel(); 

    public Random rnd = new Random(); 
    public static TestViewModel Instance 
    { 
     get 
     { 
      return _instance; 

     } 
    } 

    private ObservableCollection<TestModel> _testModels; 

    private TestViewModel() 
    { 
     _testModels = new ObservableCollection<TestModel>(); 
    } 

    public ObservableCollection<TestModel> TestModels 
    { 
     get { return _testModels;} 
     set 
     { 
      _testModels = value; 
      PropertyChanged?.Invoke(this,new PropertyChangedEventArgs(null)); 
     } 
    } 
} 

Einfacher Testfall, den ich versuche zu bekommen

for (var i = 0; i != 100; i++) 
{ 
    TestViewModel.Instance.TestModels.Add(new TestModel()); 
} 
+0

verwenden beide C# 6? Können Sie überprüfen, ob der Konverter aufgerufen wird? – sexta13

Antwort

1

Sie Bindung an die TestModels Sammlung zu arbeiten, so wird der Konverter nur, wenn die betreffenden Eigenschaftsänderungen aufgerufen gehen werden. Ihre Schleife ändert die Elemente innerhalb der Sammlung, aber sie ändert nicht den Wert von TestModels selbst. Wenn Sie möchten, dass dies funktioniert, haben Sie grundsätzlich zwei Möglichkeiten:

1) Verwenden Sie ein angehängtes Verhalten, und machen Sie es zur INotifyCollectionChanged CollectionChanged-Eigenschaft, wenn die TestModels Bindung zuerst erfolgt. Es wird dann eine Möglichkeit benötigen, das Ergebnis zurück zum Label zu bringen, was mit einer separaten angehängten Eigenschaft erreicht werden kann.

2) Machen Sie all dies in Ihrem Ansichtsmodell, das ist wirklich, wo es sowieso gemacht werden sollte. Jedes Mal, wenn Sie feststellen, dass Sie nur die einfachsten, anwendungsunabhängigen Aufgaben in Ihren Konvertern ausführen, ist dies normalerweise ein Zeichen dafür, dass Ihre Ansichtsmodellschicht nicht ordnungsgemäß funktioniert.