C# 如何在wpfviewmodel中实现可观测int?
在我的mvvm视图模型中,我有这样的字段C# 如何在wpfviewmodel中实现可观测int?,c#,wpf,mvvm,C#,Wpf,Mvvm,在我的mvvm视图模型中,我有这样的字段 public int Delta { get; private set; } 但是,当我这样更新它时: Delta = newValue; UI未刷新 我在想数据绑定可以帮我做到这一点。例如,我可以将集合声明为ObservableCollection,然后数据绑定就可以工作了 但是没有可观察的,怎么说视图需要刷新呢 可能我应该引发一些事件“notify property changed”或其他什么?只需在类中实现INotifyPropertyChan
public int Delta { get; private set; }
但是,当我这样更新它时:
Delta = newValue;
UI未刷新
我在想数据绑定可以帮我做到这一点。例如,我可以将集合声明为ObservableCollection
,然后数据绑定就可以工作了
但是没有可观察的,怎么说视图需要刷新呢
可能我应该引发一些事件“notify property changed”或其他什么?只需在类中实现INotifyPropertyChanged接口,并使用它为属性引发PropertyChanged,然后UI将更新。如果您使用的是MVVM项目模板,那么很有可能您已经实现了一个助手方法,您只需要使用它
可观察集合自动引发事件,但对于您自己的属性,您必须自己引发事件 一个很好的例子是: 我建议使用mvvm light:,我在silverlight和wpf应用程序中使用了它。非常易于使用,并在模型、视图模型和视图之间提供消息系统。您有两种选择:
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
属性,可以完全避免该参数。