Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

how to implement observable int in wpf ViewModel?

Tags:

c#

mvvm

wpf

In my mvvm ViewModel I have such field

public int Delta { get; private set; }

However when I update it like that:

Delta = newValue;

UI is not refreshed.

I was thinking that databinding will do that for me. For example I can declare collection as ObservableCollection and then databinding will work.

However there are no ObservableInt, how to say View that it need to be refreshed then?

Probably I should raise some event "notify property changed" or something?

like image 614
Oleg Vazhnev Avatar asked Nov 29 '11 18:11

Oleg Vazhnev


4 Answers

You have two choices:

  1. Implement the INotifyPropertyChanged interface on your class.
  2. Inherit from DependencyObject and implement Delta as a DependencyProperty.

The simplest option is #1. You can implement the INotifyPropertyChanged interface on your class quite easily:

public class YourClass : INotifyPropertyChanged
{

  private int _delta;
  public int Delta
  {
      get { return _delta; }
      set { _delta = value; PropertyChanged?.Invoke(nameof(Delta)); }
  }

  public event PropertyChangedEventHandler PropertyChanged;
}

You can read more about using and implementing dependency properties on MSDN.

like image 192
LBushkin Avatar answered Oct 21 '22 08:10

LBushkin


While we're at it with improving the answer, some of the other new additions of c# 6.0 and 7.0 help make it ever more compact:

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

This way, you aren't using any "embedded values" (i.e - the property's name) and are keeping the code refactor-safe.

And there's also no need for redundant code blocks due to c# 6.0 and 7.0's new Expression body features

like image 35
Leeor Vardi Avatar answered Oct 21 '22 08:10

Leeor Vardi


Using @LBushKin's Answer, i modified it to

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

and to set it up:

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 UI to be able to use the Prop
        DataContext = this;
    }

and to use it:

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

There is also a Collection and 2-Properties version here: Utils.ObservableProperties.cs (this repo contains several related classes)

like image 5
BananaAcid Avatar answered Oct 21 '22 07:10

BananaAcid


Just implement INotifyPropertyChanged Interface in your class and use it to raise a PropertyChanged for your Property and then UI will update. If you are using an MVVM project template then there is a good chance you already have a helper method implemented you only need to use it.

MSDN INotifyPropertyChanged

GalaSoft MVVM Light Toolkit

like image 3
BigL Avatar answered Oct 21 '22 07:10

BigL