微软应该为INotifyPropertyChanged实现一些时髦的东西,就像在自动属性中,只需要指定{get;设置;通知;} 我认为这样做很有意义。或者做这个手术有什么并发症吗?
我们能在属性中实现类似notify的东西吗。在你的类中实现INotifyPropertyChanged是否有一个优雅的解决方案,或者唯一的方法是在每个属性中引发PropertyChanged事件。
如果不是,我们可以写一些东西来自动生成一段代码来引发PropertyChanged事件?
微软应该为INotifyPropertyChanged实现一些时髦的东西,就像在自动属性中,只需要指定{get;设置;通知;} 我认为这样做很有意义。或者做这个手术有什么并发症吗?
我们能在属性中实现类似notify的东西吗。在你的类中实现INotifyPropertyChanged是否有一个优雅的解决方案,或者唯一的方法是在每个属性中引发PropertyChanged事件。
如果不是,我们可以写一些东西来自动生成一段代码来引发PropertyChanged事件?
当前回答
从。net 4.5开始,终于有了一个简单的方法。
. net 4.5引入了一个新的调用者信息属性。
private void OnPropertyChanged<T>([CallerMemberName]string caller = null) {
// make sure only to call this if the value actually changes
var handler = PropertyChanged;
if (handler != null) {
handler(this, new PropertyChangedEventArgs(caller));
}
}
在函数中添加比较器可能也是一个好主意。
EqualityComparer<T>.Default.Equals
更多的例子在这里和这里
参见调用者信息(c#和Visual Basic)
其他回答
我写了一篇文章来帮助你(https://msdn.microsoft.com/magazine/mt736453)。你可以使用SolSoft。DataBinding NuGet包。然后你可以这样写代码:
public class TestViewModel : IRaisePropertyChanged
{
public TestViewModel()
{
this.m_nameProperty = new NotifyProperty<string>(this, nameof(Name), null);
}
private readonly NotifyProperty<string> m_nameProperty;
public string Name
{
get
{
return m_nameProperty.Value;
}
set
{
m_nameProperty.SetValue(value);
}
}
// Plus implement IRaisePropertyChanged (or extend BaseViewModel)
}
好处:
基类是可选的 没有对每个“设定值”进行反思 可以具有依赖于其他属性的属性,并且它们都自动引发适当的事件(本文有一个这样的示例)
如果你在。net 4.5中使用动态,你不需要担心INotifyPropertyChanged。
dynamic obj = new ExpandoObject();
obj.Name = "John";
如果Name被绑定到某个控件,它就可以正常工作。
另一个组合解决方案是使用StackFrame:
public class BaseViewModel : INotifyPropertyChanged
{
public event PropertyChangedEventHandler PropertyChanged;
protected void Set<T>(ref T field, T value)
{
MethodBase method = new StackFrame(1).GetMethod();
field = value;
Raise(method.Name.Substring(4));
}
protected void Raise(string propertyName)
{
var temp = PropertyChanged;
if (temp != null)
{
temp(this, new PropertyChangedEventArgs(propertyName));
}
}
}
用法:
public class TempVM : BaseViewModel
{
private int _intP;
public int IntP
{
get { return _intP; }
set { Set<int>(ref _intP, value); }
}
}
我正在编写一个处理INotifyPropertyChanged的库,主要思想是使用动态代理来通知更改。
回购在这里:CaulyKan/NoMorePropertyChanged
使用这个库,你可以写:
public dynamic Test1Binding { get; set; }
public TestDTO Test1
{
get { return (TestDTO)Test1Binding; }
set { SetBinding(nameof(Test1Binding), value); }
}
然后将所有绑定和修改转到Test1Binding,无论TestDTO有多复杂,它都会自动通知PropertyChange和CollectionChanged。
它还可以处理依赖关系。
[DependsOn("Test1Binding.TestString")]
public string Test2
{
get { return Test1Binding.TestString; }
}
请给我一些建议。
从。net 4.5开始,终于有了一个简单的方法。
. net 4.5引入了一个新的调用者信息属性。
private void OnPropertyChanged<T>([CallerMemberName]string caller = null) {
// make sure only to call this if the value actually changes
var handler = PropertyChanged;
if (handler != null) {
handler(this, new PropertyChangedEventArgs(caller));
}
}
在函数中添加比较器可能也是一个好主意。
EqualityComparer<T>.Default.Equals
更多的例子在这里和这里
参见调用者信息(c#和Visual Basic)