我用了几天时间来改进我的MVVM应用程序,但是我发现我实际上并不知道什么是正确的方法。
在mvvm中进行绑定的正确方法是什么?
选项一:
<img src="data:image/png;base64,YOUR_BASE64_HERE"/>
选项二
public class CustomerViewModel : ViewModelBase
{
public CustomerViewModel(Customer c)
{
_customer = c;
}
private readonly Customer _customer;
public string CustomerName
{
get { return _customer.Name; }
set
{
_customer.Name = value;
RaisePropertChanged("CustomerName");
}
}
}
答案 0 :(得分:1)
假设这两种解决方案都适合你 -
如果您只有一个属性(CustomerName)要绑定到您的视图,那么选项1.正如@Default正确指出的,如果您使用选项2,则无法在将值更新回Customer c
对象时您更改CustomerName
属性的值。
如果您需要绑定Customer的所有属性。直接绑定Customer对象并确保Customer类实现INotifyPropertyChanged接口。
所以它会像这样 -
public class CustomerViewModel : ViewModelBase{
public CustomerViewModel(Customer c){
_customer = c;
}
private readonly Customer _customer;
public Customer Customer{
get{return _customer;}
set{_customer.Name = value;
RaisePropertChanged("Customer");
}
}
}
public Customer:INotifyPropertyChanged
{
#INotifyPropetyChanged implementation
private string _customerName;
public string CustomerName{
get{return _customerName;}
set{_customerName = value;
RaisePropertChanged("CustomerName");
}
}
然后用CustomerViewModel.Customer.Name
修改强> 在旁注 - 再次@Default正确指出...确保将数据的持久性从模型分离回数据库以便正确处理。即,只有在单击“保存”按钮等时才将其保存到数据库中。否则,每次更改属性都会调用太多。还有多个用户更新相同视图模型的问题。你只需记住这些要点而不是违反它们。
答案 1 :(得分:1)
这是一个有趣的问题,如何处理WPF应用程序中的普通对象。一方面,您通常不想将INPC和其他UI相关内容添加到业务对象中,因为它们可能在应用程序的其他部分中使用,与WPF无关。另一方面,创建与普通对象有许多共同点的单独ViewModel是一个很大的开销。最近我在Pluralsight上看到了关于这个话题的精彩课程: https://app.pluralsight.com/library/courses/wpf-mvvm-advanced-model-treatment/description
作者坚持使用选项一方法,当POCO对象被视图模型包装时,它们依次实现INPC和IDataErrorInfo接口,跟踪更改等。 作者建议使用T4模板为每个POCO对象创建VM包装器。借助反射的T4模板中的逻辑从平面对象中提取属性并在相应的VM中生成包装器属性。有趣的方法,值得尝试。
答案 2 :(得分:0)
一般情况下,我使用MVVM中的Option 2和automapper将模型映射到视图模型,反之亦然。我认为这完全取决于你想用VM做什么以及差异有多大。
我在VM类上工作的项目包含更多字段和逻辑,直接使用VM的属性而不是像在选项1中那样对象属性的属性更加舒适:CustomerViewModel.Customer.Name