Reputation: 2538
I have a model that updates itself in the background. Currently I'm using INotifyPropertyChanged on the Model, but I've been told thats a bad idea as the model should be UI independent.
Is there a prefered pattern for updating the ViewModel when the Model changes in the MVVM design pattern?
Upvotes: 2
Views: 2818
Reputation: 13839
Two comments:
For instance:
class MyViewModel : INotifyPropertyChanged
{
public event PropertyChangedEventHandler PropertyChanged;
private void NotifyPropertyChanged(String info)
{
if (PropertyChanged != null)
{
PropertyChanged(this, new PropertyChangedEventArgs(info));
}
}
public MyViewModel(MyModel mdl)
{
mdl.PropertyChanged +=
new PropertyChangedEventHandler(
mdl_PropertyChanged);
_mdl = mdl;
}
private MyModel _mdl = null;
void mdl_PropertyChanged(object sender,
PropertyChangedEventArgs e)
{
if (e.PropertyName == "Foo")
{
this.Foo = _mdl.Foo;
}
}
public int Foo
{
get
{
lock(_foo_Lock)
{
return _foo;
}
}
set
{
lock(_foo_Lock)
{
_foo = value;
}
NotifyPropertyChanged("Foo");
}
}
private readonly object _foo_Lock = new object();
private int _foo = 0;
}
EDIT: I don't actually suggest using hard coded strings for your property names. Here's a helper class you can use to get the property name during construction using reflection. Then create an AbstractViewModel base class. You can then inherit from AbstractViewModel and implement properties like this:
#region IsCheckable
public bool IsCheckable
{
get
{
lock(m_IsCheckable_Lock)
{
return m_IsCheckable;
}
}
protected set
{
bool fire = false;
lock(m_IsCheckable_Lock)
{
if (m_IsCheckable != value)
{
m_IsCheckable = value;
fire = true;
}
}
if(fire)
{
NotifyPropertyChanged(m_IsCheckableArgs);
}
}
}
private readonly object m_IsCheckable_Lock = new object();
private bool m_IsCheckable = false;
static readonly PropertyChangedEventArgs m_IsCheckableArgs =
NotifyPropertyChangedHelper.CreateArgs<MyViewModel>(o =>
o.IsCheckable);
#endregion
Upvotes: 3
Reputation: 14726
The purpose of the ViewModel is to allow the model to be ui independent.
Just let the viewmodel listen to an event from the model
public MyViewModel(IView view, IModel model) {
model.SomeEvent += HandleSomeEvent;
....
}
If you want to send INotifyPropertyChanged you need switch to the uithread first.
(If your model lives longer than the viewmodel you should look at some weak reference event pattern to allow the GC to clean up the viewmodel)
Upvotes: 0
Reputation: 7709
the model should be UI independent.
...well the model certainly should not be aware of the View, which is why you would make your model (or ViewModel) implement INotifyPropertyChanged, so the View can bind to Properties on the Model (or VM), and let the framework's change notification inform the View of changes (so your model doesn't need to)
Of course, if you are making changes to the UI based on data from a background thread, you will need to safely dispatch them to the UI thread - you can either use a standard .net threading mechanism (like BackgroundWorker) or you can use WPF's Dispatcher class.
Upvotes: 2