Подтвердить что ты не робот

Как реализовать наблюдаемый int в wpf ViewModel?

В моем mvvm ViewModel у меня есть такое поле

public int Delta { get; private set; }

Однако, когда я обновляю его так:

Delta = newValue;

Пользовательский интерфейс не обновляется.

Я думал, что привязка данных сделает это для меня. Например, я могу объявить коллекцию как ObservableCollection, а затем будет работать привязка данных.

Однако нет ObservableInt, как сказать View, что его нужно обновить тогда?

Возможно, я должен поднять какое-то событие "изменить свойство уведомления" или что-то еще?

4b9b3361

Ответ 1

У вас есть два варианта:

  • Внедрите INotifyPropertyChanged интерфейс в своем классе.
  • Наследовать от DependencyObject и реализовать Delta как DependencyProperty.

Самый простой вариант - # 1. Вы можете легко реализовать интерфейс INotifyPropertyChanged в своем классе:

public class YourClass : INotifyPropertyChanged
{

  private int _delta;
  public int Delta
  {
      get { return _delta; }
      set { _delta = value; NotifyPropertyChanged("Delta"); }
  }

  public event PropertyChangedEventHandler PropertyChanged;
  private void NotifyPropertyChanged(String propertyName)
  {
      PropertyChangedEventHandler handler = PropertyChanged;
      if (null != handler)
      {
          handler(this, new PropertyChangedEventArgs(propertyName));
      }
  }
  }

Вы можете больше узнать о использовании и внедрении свойств зависимостей в MSDN.

Ответ 2

Просто реализуйте интерфейс INotifyPropertyChanged в своем классе и используйте его, чтобы поднять PropertyChanged для вашего свойства, а затем обновить пользовательский интерфейс. Если вы используете шаблон проекта MVVM, то есть хороший шанс, что у вас уже есть вспомогательный метод, вам нужно только его использовать.

MSDN INotifyPropertyChanged

GalaSoft MVVM Light Toolkit

Ответ 3

ObservableCollection автоматически генерирует события, но для ваших собственных свойств вы должны сами создавать события.

Хороший пример: http://www.codeproject.com/Tips/228352/Naming-Properties-in-MVVM?display=Print

Я бы предложил использовать mvvm light: http://mvvmlight.codeplex.com, я использовал его в приложениях silverlight и wpf. Очень проста в использовании и обеспечивает систему сообщений между моделью, моделью просмотра и представлением.

Ответ 4

Используя @LBushKin Ответ, я изменил его на

public class Prop<T> : INotifyPropertyChanged
{
    private T _value;
    public T Value
    {
        get { return _value; }
        set { _value = value; NotifyPropertyChanged("Value"); }
    }

    public event PropertyChangedEventHandler PropertyChanged;
    internal void NotifyPropertyChanged(String propertyName)
    {
        PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
    }
}

и настроить его:

class MainWindow ...
    // a bool with initial value of true
    public static Prop<bool> optionBool { get; set; } = new Prop<bool>{ Value = true };

    private void Window_Loaded(object sender, RoutedEventArgs e)
    {
        // connect
        DataContext = this;
    }

и использовать его:

<Grid ...
    <CheckBox Content="Da Check" ... IsChecked="{Binding optionBool.Value}"/>

Ответ 5

Пока мы с этим улучшаем ответ, некоторые из других новых дополнений С# 6.0 и 7.0 помогают сделать его еще более компактным:

public class Prop<T> : INotifyPropertyChanged
{
    private T _value;

    public T Value
    {
        get => _value; 
        set { _value = value; NotifyPropertyChanged(nameof(_value)); }
    }

    public event PropertyChangedEventHandler PropertyChanged;

    internal void NotifyPropertyChanged(String propertyName) => 
        PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
}

Таким образом, вы не используете какие-либо "внедренные значения" (например, имя свойства) и сохраняете рефакторинг кода безопасным.

Кроме того, нет необходимости в избыточных блоках кода из-за новых функций тела выражения С# 6.0 и 7.0