我现在面临在我的WPF MVVM一些设计问题(基于棱镜)应用程序,很乐意得到您的指点。 我的模型是非常简单的:
public class Customer
{
public string FirstName {get;set;}
public string LastName {get;set;}
}
正如你所看到的,我没有为我的模型类中的任何INotifyPropertyChnaged支持。 我也有视图模型为为CustomerDetails屏幕,支持INotifyPropertyChanged的。
public class CustomerDetailsViewModel:INotifyPropertyChanged /*Or NotificationObject*/
{
/*INotifyPropertyChanged event */
private Customer item;
public Customer Item
{
get{return item;}
set
{
item=value;
//Raise PropertyChanged
//Set IsDirty to true
}
}
}
在我看来,我使用绑定到Item.FirstName和我的视图模型被更新。 我的问题是 - 因为只有名字属性被通过视图更新,模型本身并不支持INotifyPropertyChanged的,因此项目制定者没有被调用,并且IsDirty保持等于假(因此不会对更新IsDirty通知在UI)。
我知道我可以支持INotifyPropertyChanged的模型,然后注册在视图模型的Item.PropertyChanged事件,实际上是IsDirty设置为true,但是 - 因为我还使用CodeFirst,和我的服务器端之间共享我的模型类我的客户端(不使用添加服务引用),我不想给INotifyPreoprtyChanged东西添加到我的服务器端。
我considaring创建新项目,将使用T4模板复制一个个都是我的实体(如客户),并加入每一个模型INotifyPropertyChanged的支持。 那是什么,似乎合理与否? 任何其他建议?
谢谢!
选项1。
独立的实体,其被客户端和服务器(DTO)之间传送,从实体,其是在客户端模式。 实施INPC
的车型。 使用这些实体之间的映射。
选项2。
绑定视图只能查看模型属性。 使视图模型属性,其中包裹相应模型属性。
方案3。
是前两个选项的组合。 不要聚集在视图模型的模型。 使用模型和视图模型之间的映射。 使视图模型特性,这对应于属性建模。
那么你的方法根本就不是最好的。 更好的办法是使用一个虚拟机这样的
public class CustomerDetailsViewModel : INotifyPropertyChanged
{
public CustomerDetailsViewModel(Customer customer)
{
_item = customer;
}
private Customer _item;
public string FirstName
{
get { return _item != null ? _item.FirstName : null; }
set
{
if (_item == null)
_item = new Customer(); // just an example, probably it's not the desired behavior
_item.FirstName = value;
RaisePropertyChanged(...);
}
}
...
}
这将坚持MVVM的精神。
如果你希望你的用户界面注意到,当你的模型属性改变 ,你的模型类必须实现INotifyPropertyChanged
和类似的MVVM接口( IDataErrorInfo
才能,等...) Notify
到的用户界面property changed
。
那是因为你并不总是从该视图模型,你必须实现更新模型INotifyProperyChanged
并通知更改。
在视图模型包装相应的模特属性用来当你无法实现INotifyPropertyChanged
模型类,这使得视图模型增长速度非常快,产生不必要的代码重复。
方案,例如:
public class Customer
{
public string FirstName {get;set;}
public string LastName {get;set;}
// Changes the first name.
public void ChangeFirstName(string newName)
{
FirstName = newName;
//The UI will never know that the property changed, and it won't update.
}
}
解:
实施INotifyPropertyChanged
在你的模型类,创建backing fields
到你properties
,并为每个属性setter
,在后set
操作,提高OnPropertyChanged
与调用的方法property
名称。
我认为你是在正确的轨道上。 在服务器端,你并不需要INotifyPropertyChanged
,因此不会在服务器端把它添加到域类。
你可能只是添加一些构建符号,如“WPF”到客户的项目; 并在代码首先定义实现INotifyPropertyChanged
仅当有“WPF”构建符号。 然后,只需添加您的服务器端领域类的链接到您的演示应用程序。 就像是;
#if WPF
public class MyEntity : INotifyPropertyChanged
#else
public class MyEntity
....
如果你不喜欢混乱与INotifyPropertyChanged的代码模型,你可以尝试使用NuGet包称为PropertyChanged.Fody
你可以用它像这样;
using PropertyChanged;
[ImplementPropertyChanged]
public class Customer
{
public string FirstName {get;set;}
public string LastName {get;set;}
}
在这个类的任何公共财产将支持INotifyPropertyChanged的