WPF and MVVM tutorial 05, The basic ViewModel.

As we saw in the previous posts, a view model should be an abstract implementation of what the view needs to show about the model. We should implement an observable collection of something, we should implement an INotifyPropertyChanged interface and we should have a collection of RelayCommands.

For these reasons, it simply to understand that we need a basic abstract ViewModel class, just to recycle some code.

 

The Basic View Model.

  1: namespace MVVM.ViewModel {
  2:     public abstract class ViewModel:INotifyPropertyChanged,IDisposable {
  3: 
  4:         INavigationActions navigator;
  5: 
  6:         public ViewModel() {
  7:             navigator = Application.Current as INavigationActions;
  8:             if (navigator != null) {
  9:                 navigator.PropertyChanged += application_PropertyChanged;
 10:             }
 11:         }
 12: 
 13:         void application_PropertyChanged(object sender, PropertyChangedEventArgs e) {
 14:             if (string.IsNullOrEmpty(e.PropertyName) || e.PropertyName == "View")
 15:                 OnPropertyChanged("View");
 16:         }
 17: 
 18:         public INavigationActions NavigationActions {
 19:             get {
 20:                 return navigator;
 21:             }
 22:             set {
 23:                 if (navigator != value) {
 24:                     SetAction(value);
 25:                     OnPropertyChanged("NavigationActions");
 26:                 }
 27:             }
 28:         }
 29: 
 30:         protected virtual void SetAction(INavigationActions value) {
 31:             if (navigator != null)
 32:                 navigator.PropertyChanged -= application_PropertyChanged;
 33:             navigator = value;
 34:             if (navigator != null)
 35:                 navigator.PropertyChanged += application_PropertyChanged;
 36:         }
 37: 
 38:         #region INotifyPropertyChanged Members
 39:         /// <summary>
 40:         /// Raised when a property has a new value
 41:         /// </summary>
 42:         public event PropertyChangedEventHandler PropertyChanged;
 43:         /// <summary>
 44:         /// Raise the event
 45:         /// </summary>
 46:         /// <param name="propertyName">Property name that has new value</param>
 47:         protected virtual void OnPropertyChanged(string propertyName) {
 48:             PropertyChangedEventHandler handler = this.PropertyChanged;
 49:             if (handler != null) {
 50:                 var e = new PropertyChangedEventArgs(propertyName);
 51:                 handler(this, e);
 52:             }
 53:         }
 54:         #endregion
 55: 
 56:         #region IDisposable Members
 57:         /// <summary>
 58:         /// Implementation of the dispose method
 59:         /// </summary>
 60:         public void Dispose() {
 61:             this.OnDispose();
 62:         }
 63:         /// <summary>
 64:         /// The child class should implement a personal dispose procedure
 65:         /// </summary>
 66:         protected virtual void OnDispose() {
 67:             //do nothing because abstract
 68:         }
 69: 
 70:         #endregion
 71:     }
 72: }

A small summary of our code:

  1. An implementation of the INotifyPropertyChanged that we can use in the concrete views.
  2. An implementation of the IDisposable in order to clean our objects like collections and repositories.
  3. An INavigator interface to implement the navigation of our application. In this case I am using the navigator pattern for composite WPF applications. Beware because this is my implementation for the navigation but it depends on how you design your app (multi-win, tab, MDI).

The INavigator implementation.

The are thousands of ways to implement a navigator engine. The only common purpose in MVVM is that the View Model doesn’t know the View but the View knows the View Model. So in our example which part of the View can interact with the application and doesn’t need to know the View Model? The app.xaml file!

My idea is this one:

Leave a comment

Your email address will not be published. Required fields are marked *