WPF MVVM - 在视图模型类中使用模型
我想知道在视图模型中模型类的正确使用是什么。作为 MVVM,我使用 Caliburn Micro。
第一个替代方案。
模型类:
public class CurrentUser : IDataErrorInfo
{
public string Nick { get; set; }
public string Password { get; set; }
//...
}
在视图模型类中使用模型:
[Export(typeof(ILogOnViewModel))]
public class LogOnViewModel : Screen
{
public CurrentUser CurrentUser { get; set; }
//bind on control in view
public string CurrentNick
{
get { return CurrentUser.Nick; }
set
{
CurrentUser.Nick = value;
NotifyOfPropertyChange(() => CurrentNick);
}
}
//bind on control in view
public string CurrentPassword
{
get { return CurrentUser.Password; }
set
{
CurrentUser.Password = value;
NotifyOfPropertyChange(() => CurrentPassword);
}
}
}
第二个替代方案:
模型类:
public class CurrentUser : IDataErrorInfo, INotifyPropertyChanged
{
public event PropertyChangedEventHandler PropertyChanged;
private void NotifyPropertyChanged(String info)
{
if (PropertyChanged != null)
{
PropertyChanged(this, new PropertyChangedEventArgs(info));
}
}
public string Nick
{
get { return _nick; }
set
{
_nick = value;
NotifyPropertyChanged("Nick");
}
}
public string Password
{
get { return _password; }
set
{
_password = value;
NotifyPropertyChanged("Password");
}
}
//...
}
在视图模型类中使用模型类:
[Export(typeof(ILogOnViewModel))]
public class LogOnViewModel : Screen
{
//bind on UI control
public CurrentUser CurrentUser { get; set; }
}
I would like to know what is correct using of model class in in view model. As MVVM I use Caliburn Micro.
First alternative.
Model class:
public class CurrentUser : IDataErrorInfo
{
public string Nick { get; set; }
public string Password { get; set; }
//...
}
Using model in view model class:
[Export(typeof(ILogOnViewModel))]
public class LogOnViewModel : Screen
{
public CurrentUser CurrentUser { get; set; }
//bind on control in view
public string CurrentNick
{
get { return CurrentUser.Nick; }
set
{
CurrentUser.Nick = value;
NotifyOfPropertyChange(() => CurrentNick);
}
}
//bind on control in view
public string CurrentPassword
{
get { return CurrentUser.Password; }
set
{
CurrentUser.Password = value;
NotifyOfPropertyChange(() => CurrentPassword);
}
}
}
Second alternative:
Model class:
public class CurrentUser : IDataErrorInfo, INotifyPropertyChanged
{
public event PropertyChangedEventHandler PropertyChanged;
private void NotifyPropertyChanged(String info)
{
if (PropertyChanged != null)
{
PropertyChanged(this, new PropertyChangedEventArgs(info));
}
}
public string Nick
{
get { return _nick; }
set
{
_nick = value;
NotifyPropertyChanged("Nick");
}
}
public string Password
{
get { return _password; }
set
{
_password = value;
NotifyPropertyChanged("Password");
}
}
//...
}
Using model class in view model class:
[Export(typeof(ILogOnViewModel))]
public class LogOnViewModel : Screen
{
//bind on UI control
public CurrentUser CurrentUser { get; set; }
}
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
第一种选择会更好,因为它从视图中更好地封装了模型。
但是您应该在ViewModel上实现
IDataErrorInfo
和INotifyPropertyChanged
,因为ViewModel应该是通知用户的对象更改和错误的界面。The first alternative would be better, since it encapsulates your model better from the View.
But you should implement
IDataErrorInfo
andINotifyPropertyChanged
on the ViewModel, since the ViewModel should be the object that notifies your user interface of changes and errors.我更喜欢第一种方法。有几个原因:
View
永远不应该访问Model
。ViewModel
包装/外观了从Model
绑定到View
所需的所有属性。它添加了促进View
功能所需的任何附加属性、集合和命令,同时防止将代码放在代码后面。IDataErrorInfo
和INotifyPropertyChanged
有助于View
而不是ViewModel
。由于View
仅与ViewModel
通信,因此它们应该位于ViewModel
内部。I would prefer the first approach. There are a few reasons why:
Model
should never be accessible toView
.ViewModel
wraps/facades all properties required to be bound toView
fromModel
. It adds any additional properties, collections and commands required to facilitateView
's functionality and while preventing putting code in code behind.IDataErrorInfo
andINotifyPropertyChanged
facilitateView
notViewModel
. And sinceView
only communicates withViewModel
, they should be insideViewModel
.我会使用第二种方法。如果您正在寻找使用第二种方法的示例应用程序,那么您可能会找到WPF 应用程序框架 (WAF) 项目很有趣。
I would use the second approach. If you are looking for sample applications that use the second approach then you might find the WPF Application Framework (WAF) project interesting.
我建议从第二种方法开始。它可以让您免于输入大量重复的桥接属性。如果您遇到需要包装在视图模型上的属性,请对该属性执行此操作,然后更新视图的绑定。您的模型和视图模型都可以实现 IDataErrorInfo 和 INotifyPropertyChanged。当模型中的某些逻辑更改属性时,后者非常有用,因为它随后会传播到视图。通过基类实现这些接口,您可以同时拥有 ModelBase 和 ViewModelBase 抽象类,后者派生自前者。
I'd recommend starting off with the second approach. It could save you from typing out a lot of repetitive bridging properties. If you encounter a property that needs to be wrapped on the View Model, then do so for that property then update the View's binding(s). Both your Model and View Model can implement IDataErrorInfo and INotifyPropertyChanged. The latter is quite useful when some logic in your Model changes a property since it will then be propagated to the View. Implementing those interfaces via base classes, you could have both a ModelBase and a ViewModelBase abstract classes, where the latter derives from the former.