如何在wpf ViewModel中实现observable int?

时间:2011-11-29 18:42:06

标签: c# wpf mvvm

在我的mvvm ViewModel中,我有这样的字段

public int Delta { get; private set; }

然而,当我更新它时:

Delta = newValue;

UI未刷新。

我在想,数据绑定会为我做到这一点。例如,我可以将集合声明为ObservableCollection,然后数据绑定将起作用。

但是没有ObservableInt,怎么说查看它需要刷新呢?

可能我应该提出一些事件“通知财产已更改”或其他什么?

5 个答案:

答案 0 :(得分:34)

您有两种选择:

  1. 在您的课程上实施INotifyPropertyChanged界面。
  2. 继承自DependencyObject并将Delta实现为DependencyProperty。
  3. 最简单的选择是#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上阅读有关using and implementing dependency properties的更多信息。

答案 1 :(得分:4)

使用@LBushKin的答案,我将其修改为

dbase_create()

并进行设置:

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

这里还有一个Collection和2-Properties版本: Utils.ObservableProperties.cs(此repo包含几个相关的类)

答案 2 :(得分:3)

只需在您的类中实现INotifyPropertyChanged接口,并使用它为您的Property引发PropertyChanged,然后UI将更新。如果您正在使用MVVM项目模板,那么您很可能已经实现了一个只需要使用它的辅助方法。

MSDN INotifyPropertyChanged

GalaSoft MVVM Light Toolkit

答案 3 :(得分:2)

ObservableCollection自动引发事件,但对于您自己的属性,您必须自己引发事件。

这里有一个很好的例子:http://www.codeproject.com/Tips/228352/Naming-Properties-in-MVVM?display=Print

我建议使用mvvm light:http://mvvmlight.codeplex.com,我在silverlight和wpf应用程序中使用它。非常易于使用,并在模型,视图模型和视图之间提供消息系统。

答案 4 :(得分:1)

虽然我们在改进答案的同时,c#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));
}

这样,你就不会使用任何&#34; embbeded values&#34; (即 - 财产的名称)并保持代码重构安全。

由于c#6.0和7.0的新表情主体功能,也不需要冗余代码块