我还没有找到确切的答案。有些人提到直接绑定到模型不适合MVVM,但是我试图确定以下模式是否仍然遵循MVVM:
查看:
<TextBox Text="{Binding InfoForProcessing.BatchId}"/>
<TextBox Text="{Binding InfoForProcessing.BatchStatus}"/>
视图模型:
private ProcessingTaskModel _infoForProcessing;
public ProcessingTaskModel InfoForProcessing
{
get
{
return _infoForProcessing;
}
private set
{
_infoForProcessing = value;
RaisePropertyChanged();
}
}
....
//doing some processing...then tell Model to populate the data:
InfoForProcessing.ResolveBatchInfo(...);
模型:(实现INotifyPropertyChanged)
private string _batchId;
public string BatchId //VIEWABLE
{
get
{
return _batchId;
}
private set
{
_batchId = value;
RaisePropertyChanged();
}
}
private string _batchStatus;
public string BatchStatus //VIEWABLE
{
get
{
return _batchStatus;
}
private set
{
_batchStatus = value;
RaisePropertyChanged();
}
}
public bool ResolveBatchInfo(...){
//Get data from Database...
...
//Now Populate Properties with retrieved data (or return false on error)
BatchId = dr[0].ToString();
BatchStatus = dr[1].ToString();
return true;
}
我看到了另一种方法。我可以将这些属性复制到ViewModel,绑定到它们,并让ViewModel在模型返回时填充它们。
对于我目前的项目,模型中的一些数据是将在稍后执行的查询的依赖项
我还确保尽可能地封装,并且只显示View和ViewModel需要查看的属性,同时限制setter。
答案 0 :(得分:2)
一种常见的思维方式是 - 由于某种原因 - 您无法直接绑定到视图中的模型属性。
然而,鉴于MVVM的目标是将UI / View从逻辑中抽象出来,这不会被这种形式的绑定所打破:
{Binding ViewModel.Model.Property}
这也意味着您不会始终将属性从Model复制到ViewModel。
答案 1 :(得分:1)
您的设计在我看来是不符合的,因为您的数据对象包含模型逻辑(ResolveBatchInfo
方法)。以下是两种可能的解决方案:
具有单独的View Model和Model对象。在这种情况下,每个都有自己的方法。 INPC用于Model类中的View Model类和数据库方法。 (如图here)
让您的POCO在图层之间“浮动”。这里的重要部分是除了INPC之外,对象中没有逻辑,它们只是数据。在这种设计下,您将拥有一个单独的模型类,它封装了数据操作,并且有一个返回已填充的BatchInfo
对象的方法。
我通常在自己的项目中做(2),因为它可以更好地分离关注点并限制代码/数据复制。
当然,使用这三种方法中的任何一种(我的两种加上你的方法),最重要的因素是编写有意义的代码而不是它是“纯粹的”MVVM。因此,请选择能让您的生活变得轻松的设计。
答案 2 :(得分:0)
我个人并不介意,但很多人(包括我目前工作的公司)都认为在视图模型中包装模型的属性是一种更“纯粹”的方法。对我个人而言,我认为将MVVM视为良好实践的指南非常重要,而不是绝对遵循的一套规则。在我被告知忘记包装模型的属性之前,我遇到了一些实例,只是因为它需要快速完成。
答案 3 :(得分:0)
最好将其列为子弹
我更喜欢将Models
保留为POCO类型实体,而不 保留获取模型的操作。
您所描述的Model
实际上是数据库操作的属性/属性;它的地位。
您的模型上的所有这些项目都应该在您的VM上移动并完成并相应地绑定。