Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/267.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 如何在wpfviewmodel中实现可观测int?_C#_Wpf_Mvvm - Fatal编程技术网

C# 如何在wpfviewmodel中实现可观测int?

C# 如何在wpfviewmodel中实现可观测int?,c#,wpf,mvvm,C#,Wpf,Mvvm,在我的mvvm视图模型中,我有这样的字段 public int Delta { get; private set; } 但是,当我这样更新它时: Delta = newValue; UI未刷新 我在想数据绑定可以帮我做到这一点。例如,我可以将集合声明为ObservableCollection,然后数据绑定就可以工作了 但是没有可观察的,怎么说视图需要刷新呢 可能我应该引发一些事件“notify property changed”或其他什么?只需在类中实现INotifyPropertyChan

在我的mvvm视图模型中,我有这样的字段

public int Delta { get; private set; }
但是,当我这样更新它时:

Delta = newValue;
UI未刷新

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

但是没有可观察的,怎么说视图需要刷新呢


可能我应该引发一些事件“notify property changed”或其他什么?

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


可观察集合自动引发事件,但对于您自己的属性,您必须自己引发事件

一个很好的例子是:

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

您有两种选择:

  • 在类上实现接口
  • 从DependencyObject继承并将增量实现为DependencyProperty
  • 最简单的选择是#1。您可以非常轻松地在类上实现INotifyPropertyChanged接口:

    public class YourClass : INotifyPropertyChanged
    {
    
      private int _delta;
      public int Delta
      {
          get { return _delta; }
          set { _delta = value; PropertyChanged?.Invoke(nameof(Delta)); }
      }
    
      public event PropertyChangedEventHandler PropertyChanged;
    }
    

    您可以在MSDN上阅读更多信息。

    使用@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));
        }
    }
    
    公共类属性:INotifyPropertyChanged
    {
    私人T_值;
    公共价值
    {
    获取{返回_值;}
    设置{u value=value;NotifyPropertyChanged(“value”);}
    }
    公共事件属性更改事件处理程序属性更改;
    内部无效NotifyPropertyChanged(字符串propertyName)
    {
    PropertyChanged?.Invoke(这是新的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;
        }
    
    类主窗口。。。
    //初始值为true的布尔值
    公共静态属性选项bool{get;set;}=newprop{Value=true};
    已加载私有无效窗口(对象发送器、路由目标)
    {
    //连接UI以使用道具
    DataContext=this;
    }
    
    使用它:

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

    在我们努力改进答案的同时,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));
    }
    
    公共类属性:INotifyPropertyChanged
    {
    私人T_值;
    公共价值
    {
    获取=>\u值;
    设置{u value=value;NotifyPropertyChanged(nameof(_value));}
    }
    公共事件属性更改事件处理程序属性更改;
    内部无效NotifyPropertyChanged(字符串propertyName)=>
    PropertyChanged?.Invoke(这是新的PropertyChangedEventArgs(propertyName));
    }
    
    这样,您就不用使用任何“embbedvalue”(即属性的名称),而是确保代码重构的安全


    而且,由于c#6.0和7.0的新表达式体功能,也不需要冗余代码块

    是的,您走在了正确的轨道上。您需要引发属性更改事件。google InotifyPropertyChanged但是View如何知道当某些属性被提升时,某些控件需要被提升?View将通过您拥有的绑定来了解它。+1绝对正确,但对于WPF新手,我鼓励您也查看其他答案,因为采用现有的工具包将需要更少的工作,并且使学习框架变得更加容易创建?我希望这是由C#自动生成的,就像正常情况一样property@javapowered:很遗憾,没有。您不能拥有“部分实现”的自动属性。如果需要在setter中调用方法(如本例中),则必须提供支持字段和属性实现;如果只想绑定一次而不观察更改?只是提醒一下,即使在ObservableCollection上,您也需要引发属性更改,以防对集合本身的引用发生更改。这不应该是
    nameof(value)
    而不是
    nameof(_value)
    ?通过使用
    NotifyPropertyChanged()
    方法声明上的
    CallerMemberName
    属性,可以完全避免该参数。