Binding не выводит свойство на Label

149
18 июля 2019, 20:40

В окне есть Slider и Label.

Вот код:

<Slider 
    Value="{Binding MathLevel, Mode=TwoWay}"
    Width="200" />
<Label
    Content="{Binding MathLevel}"
    HorizontalAlignment="Left"
    Margin="157,250,0,0"
    VerticalAlignment="Top" />

По идее из ViewModel.cs должно обновляться свойство MathLevel при изменении значение Value (и сразу менять само Value). А на Label выводить MathLevel при обновлении.

Но почему-то работает только первая часть замысла. Content как был 0 так и остался сколько не меняй значение Value у слайдера.

Вот свойство из ViewModel.cs

public int MathLevel
{
    get => user.Skills[0].Level;
    set {
        user.Skills[0].Level = value;
        OnPropertyChanged("Math skill level");
    }
}

А вот User.cs

class User
{
    string Name {get;set;}
    public List<Skill> Skills {get;set;} = new List<Skill>()
    {
        //Тут инициализация null нет, все ок.
    }
}

P.S

У меня на форме также находится TextBox и для него тоже есть привязка, только к другому свойству в VM. Так вот если Label код заменить на вот такой:

<Label
    Content="{Binding Name}"
    HorizontalAlignment="Left"
    Margin="157,250,0,0"
    VerticalAlignment="Top" />

И вот свойство Name из ViewModel:

public string Name
{
    get => user.Name;
    set{
        user.Name = value;
        OnPropertyChanged("Name");
    }
}

То значение из TextBox отлично заноситься в свойство из VM, а потом и на Label

Answer 1

Мы не видим всего кода, но потому что продемонстрировано можно предположить, что ошибка в ViewModel.cs, а именно в сеттере MathLevel. В событие PropertyChanged интерфейса INotifyPropertyChanged нужно передать имя свойства, которое изменилось. Так работает Binding в WPF. Т.е. попробуйте сделать следующее:

public int MathLevel
{
    get => user.Skills[0].Level;
    set {
        user.Skills[0].Level = value;
        OnPropertyChanged("MathLevel");
    }
}
Answer 2

Так видно же сразу - вы пишите в сеттере свойства какую-то белиберду:

OnPropertyChanged("Math skill level");

А должны писать имя свойства, которое должно производить уведомление:

OnPropertyChanged("MathLevel");

А если реализуете интерфейс INotifyPropertyChanged с использованием атрибута CallerMemberName, вот так:

public event PropertyChangedEventHandler PropertyChanged;
protected virtual void OnPropertyChanged([CallerMemberName] string propertyName = null)
{
    PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
}

то можете вообще не указывать имя свойства:

public int MathLevel
{
    get => user.Skills[0].Level;
    set {
        user.Skills[0].Level = value;
        OnPropertyChanged();
    }
}
READ ALSO
Проблема со SquishIt

Проблема со SquishIt

Вечер добрыйПомогите разобраться

238
c# масштабируемый график/рисунок/контрол

c# масштабируемый график/рисунок/контрол

Начал рисовать один весьма странный компонент для формы и пришел к выводу что лучше если бы он был масштабируемымКомпонент предназначен...

148
Автоматический Dispose(); у всех полей класса

Автоматический Dispose(); у всех полей класса

На сколько НЕкоректно использовать такую вот "ленивую" конструкцию диспоуза:

140
Unity3d C# Translate не работает

Unity3d C# Translate не работает

Translate просто телепортирует объект через две секундыМоя задача сделать движение объекта так: в одну сторону две секунды, в другую сторону...

176