我正在尝试在以下代码中为用例创建代码,其中通用ViewModel类从其模型“捕获”所有属性,并提供具有相同名称和类型的属性,并触发{{ 1}}事件以进行数据绑定。
有办法吗?我正在使用.NET 4.6。
PropertyChanged
答案 0 :(得分:2)
您可以使用Fody自动插入在 compile 时引发模型类所有属性的PropertyChanged
事件的代码。
然后,您可以直接绑定到Rectangle
,而无需修改它并显式实现INotifyPropertyChanged
接口。
否则,恐怕您将不得不在每个视图模型中一个一个地定义每个属性,或者在构建之前想出一种自动生成视图模型类的方法。
答案 1 :(得分:0)
您正在寻找类似的东西吗?
using System.Collections.Generic;
using System.ComponentModel;
using System.Diagnostics;
using System.Runtime.CompilerServices;
public class Rectangle : INotifyPropertyChanged
{
private double height;
public double Width { get; set; }
public double Height { get => height; set => SetField(ref height, value); }
#region INotifyPropertyChanged Implementation
public event PropertyChangedEventHandler PropertyChanged;
protected void OnPropertyChanged([CallerMemberName] string propertyName = null)
{
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
}
protected bool SetField<T>(ref T field, T value, [CallerMemberName] string propertyName = null)
{
if (EqualityComparer<T>.Default.Equals(field, value))
return false;
field = value;
OnPropertyChanged(propertyName);
return true;
}
#endregion
}
public class RectangleViewModel : MagicViewModel<Rectangle>
{
public RectangleViewModel(Rectangle model)
: base(model)
{
this.model = model;
model.PropertyChanged += (s, e) => OnPropertyChanged(e.PropertyName);
}
private Rectangle model;
public Rectangle Model { get => model; set => SetField(ref model, value); }
}
public class MagicViewModel<TModel> : INotifyPropertyChanged
{
protected readonly TModel _model;
public MagicViewModel(TModel model)
{
_model = model;
}
#region INotifyPropertyChanged Implementation
public event PropertyChangedEventHandler PropertyChanged;
public void OnPropertyChanged([CallerMemberName] string propertyName = null)
{
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
}
public bool SetField<T>(ref T field, T value, [CallerMemberName] string propertyName = null)
{
if (EqualityComparer<T>.Default.Equals(field, value))
return false;
field = value;
OnPropertyChanged(propertyName);
return true;
}
#endregion
}
public class Program
{
public static void Main(string[] args)
{
var vm = new RectangleViewModel(new Rectangle());
var calls = 0;
vm.PropertyChanged += (sender, propChangedArgs) => calls++;
vm.Model.Height = 10; // magic happened here
Debug.Assert(calls > 0);
}
}