A view model base class to use with MVVM in WPF
As I mentioned in previous posts (here, here, and here), when you develop WPF application, you’ll eventually use view models. So, instead of keep developing them from scratch, I’m posting three different alternatives for easy reference.
The simple view model
public class ViewModelBase : INotifyPropertyChanged
{
#region Implementation of INotifyPropertyChanged
public event PropertyChangedEventHandler PropertyChanged;
protected virtual void OnPropertyChanged(string propertyName)
{
OnPropertyChanged(new PropertyChangedEventArgs(propertyName));
}
protected virtual void OnPropertyChanged(PropertyChangedEventArgs args)
{
var handler = PropertyChanged;
if (handler != null)
handler(this, args);
}
#endregion
}
This is the simplest class you can have. It implements the INotifyPropertyChanged interface and provides two protected methods for you to notify that a specific property as changed. On that takes the string as a parameter, and another that takes a PropertyChangedEventArgs object. The problem with this approach is that you’ll keep creating new instances of PropertyChangedEventArgs, even though you have a limited number of properties in the class.
The smarter view model
public abstract class ViewModelBaseWithArgCache : ViewModelBase
{
private readonly Dictionary<string, PropertyChangedEventArgs> eventArgsCache;
protected ViewModelBaseWithArgCache()
{
eventArgsCache = new Dictionary<string, PropertyChangedEventArgs>();
}
#region Overrides
protected override void OnPropertyChanged(string propertyName)
{
PropertyChangedEventArgs args;
if (!eventArgsCache.ContainsKey(propertyName))
{
args = new PropertyChangedEventArgs(propertyName);
eventArgsCache.Add(propertyName, args);
}
else
{
args = eventArgsCache[propertyName];
}
OnPropertyChanged(args);
}
#endregion
}
Here, we’re overriding OnPropertyChanged(string propertyName), to provide a custom implementation. First we initialize a dictionary of
The unified view model
public class UnifiedViewModelBase : INotifyPropertyChanged
{
private readonly Dictionary<string, PropertyChangedEventArgs> eventArgsCache;
protected UnifiedViewModelBase()
{
eventArgsCache = new Dictionary<string, PropertyChangedEventArgs>();
}
#region Implementation of INotifyPropertyChanged
public event PropertyChangedEventHandler PropertyChanged;
protected void OnPropertyChanged(string propertyName)
{
PropertyChangedEventArgs args;
if (!eventArgsCache.TryGetValue(propertyName, out args))
{
args = new PropertyChangedEventArgs(propertyName);
eventArgsCache.Add(propertyName, args);
}
OnPropertyChanged(args);
}
protected void OnPropertyChanged(PropertyChangedEventArgs args)
{
var handler = PropertyChanged;
if (handler != null)
handler(this, args);
}
#endregion
}
Now, instead of have a two-level hierarchy of classes, we combined them together in a single UnifiedViewModelBase. You may want to rename this class to something like ViewModelBase.
You can download all the code in this post by clicking this link.
Hope this helps!
