Reputation:
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; }
}
Upvotes: 2
Views: 3413
Reputation: 7031
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.
Upvotes: 1
Reputation: 4548
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.
Upvotes: 0
Reputation: 30830
I would prefer the first approach. There are a few reasons why:
Model
should never be accessible to View
.ViewModel
wraps/facades all properties required to be bound to View
from Model
. It adds any additional properties, collections and commands required to facilitate View
's functionality and while preventing putting code in code behind.IDataErrorInfo
and INotifyPropertyChanged
facilitate View
not ViewModel
. And since View
only communicates with ViewModel
, they should be inside ViewModel
.Upvotes: 4
Reputation: 39620
The first alternative would be better, since it encapsulates your model better from the View.
But you should implement IDataErrorInfo
and INotifyPropertyChanged
on the ViewModel, since the ViewModel should be the object that notifies your user interface of changes and errors.
Upvotes: 5