C# WPF MVVM Binding not updating

点点圈 提交于 2019-12-02 17:38:17

问题


I'm trying to do simple binding using a converter to display count of elements inside observable collection that satisfy given enum, let's say A B C D.

The code below works when I test it with my other project, but on the most basic project binding doesn't get updated. The exact same code works inside other project (really strange).

How I'm doing the binding

<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();
    }
}

Model

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

ViewModel

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

Simple test case that I'm trying to get to work

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

回答1:


You're binding to the TestModels collection, so the converter is only going to be invoked when that property changes. Your loop changes the elements within the collection but it doesn't change the value of TestModels itself. If you want this to work then you basically have two options:

1) Use an attached behaviour and make it subscribe to the INotifyCollectionChanged CollectionChanged property when the TestModels binding is first made. It will then need some way of providing the result back to the Label, that can be achieved with a separate attached property.

2) Do all this in your view model, which is really where it should be being done anyway. Any time you find yourself doing anything but the most basic, application-independent tasks in your converters it's usually a sign that your view model layer isn't doing its job properly.



来源:https://stackoverflow.com/questions/36585758/c-sharp-wpf-mvvm-binding-not-updating

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!