Click here to Skip to main content
15,896,606 members
Articles / Desktop Programming / WPF

MVVM for Multi Platforms

Rate me:
Please Sign up or sign in to vote.
4.13/5 (6 votes)
22 Mar 2010CPOL2 min read 26.5K   354   22  
How to implement MVVM when developing a view model whose view implementation language is not certain
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

using GeographicRepresentation.Interfaces;
using GeographicRepresentation.Lib.Model;

namespace GeographicRepresentation.Lib.ViewModel
{
    /// <summary>
    /// This is a base view model for a Country
    /// </summary>
    public class CountryViewModel : ICountryViewModel
    {
        #region Members

        Country m_Country;        

        #endregion

        #region Properties

        /// <summary>
        /// A property for extracting the country value out of the view model for saving and changing the value once
        /// a refresh is called. It is for usuage only within the current namespace
        /// </summary>
        internal Country Country
        {
            get 
            { 
                return m_Country; 
            }
            set
            {
                m_Country = value;
            }
        }

        #endregion

        #region Methods

        #region Ctor

        public CountryViewModel(Country country)
        {
            m_Country = country;
        }

        #endregion

        #region ICountryViewModel Members        

        public Guid Id
        {
            get 
            {
                return m_Country.Id;
            }
        }

        /// <summary>
        /// Since the name can only be changed in edit mode, the property is declared virtual and would be overriden in the Editable View model
        /// </summary>
        public virtual string CountryName
        {
            get
            {
                return m_Country.Name;
            }
            set
            {
                throw new NotImplementedException();
            }
        }

        /// <summary>
        /// Since the size can only be changed in edit mode, the property is declared virtual and would be overriden in the Editable View model
        /// </summary>
        public virtual  int Size
        {
            get
            {
                return m_Country.Size;
            }
            set
            {
                throw new NotImplementedException();
            }
        }

        /// <summary>
        /// Since the birth date can only be changed in edit mode, the property is declared virtual and would be overriden in the Editable View model
        /// </summary>
        public virtual float BirthRate
        {
            get
            {
                return m_Country.BirthRate;
            }
            set
            {
                throw new NotImplementedException();
            }
        }

        #endregion

        #endregion
        
    }

    /// <summary>
    /// This is the Country read only view model
    /// </summary>
    public class ReadOnlyCountryViewModel : CountryViewModel, IReadonlyCountryViewModel
    {
        #region Members

        public event SimpleOperationDelegate OnBirthRateChanged;

        List<IReadOnlyCityViewModel> m_Cities;

        #endregion

        #region Methods

        #region Ctor

        public ReadOnlyCountryViewModel(Country country) : base(country)
        {
            m_Cities = new List<IReadOnlyCityViewModel>();
            // Create a view model for each of the cities which appears on the list
            for (int iter = 0; iter < country.Cities.Count; iter++)
            {
                m_Cities.Add(new ReadOnlyCityViewModel(country.Cities[iter]));
            }
        }

        #endregion

        #region IReadonlyCountryViewModel Members

        public IList<IReadOnlyCityViewModel> Cities
        {
            get 
            {
                return m_Cities;
            }
        }

        #endregion

        #region IReadOnlyObject Members

        /// <summary>
        /// Reload the data from the data manager
        /// </summary>
        public void Refresh()
        {
            DataManager.Instance.LoadDataFromStorage();
            this.Country = DataManager.Instance.GetCountry(this.Id);
            m_Cities.Clear();
            for (int iter = 0; iter < this.Country.Cities.Count; iter++)
            {
                m_Cities.Add(new ReadOnlyCityViewModel(this.Country.Cities[iter]));
            }
        }

        #endregion

        #endregion
    }

    /// <summary>
    /// This is the view model which enables to add a country or edit it
    /// </summary>
    public class EditableCountryViewModel : CountryViewModel, IEditableCountryViewModel
    {
        #region Members

        /// <summary>
        /// Hold the continents id in case this is a new Country
        /// </summary>
        Guid m_ContinentId;
        /// <summary>
        /// Hold the countries original value in case of cancelation
        /// </summary>
        Country m_OrigCountry;

        #endregion

        #region Ctor

        public EditableCountryViewModel(Country country)
            : base(country)
        {
            m_OrigCountry = new Country(country);
            m_ContinentId = Guid.Empty;
        }

        public EditableCountryViewModel(Country country, Guid continentId) : base(country)
        {
            m_OrigCountry = null;
            m_ContinentId = continentId;
        }

        #endregion

        #region IEditableObject Members

        /// <summary>
        /// The edit view model is the only place in which the property could be changed. Therefore it is overriden
        /// </summary>
        public override string CountryName
        {
            get
            {
                return base.CountryName;
            }
            set
            {
                this.Country.Name = value;
            }
        }

        /// <summary>
        /// The edit view model is the only place in which the property could be changed. Therefore it is overriden
        /// </summary>
        public override int Size
        {
            get
            {
                return base.Size;
            }
            set
            {
                this.Country.Size = value;
            }
        }

        /// <summary>
        /// The edit view model is the only place in which the property could be changed. Therefore it is overriden
        /// </summary>
        public override float BirthRate
        {
            get
            {
                return base.BirthRate;
            }
            set
            {
                this.Country.BirthRate = value;                
            }
        }

        /// <summary>
        /// Write the data into the repository
        /// </summary>
        public void Save()
        {
            if (m_ContinentId != Guid.Empty)
            {
                // this is a new country and it should be added to a continent
                Continent continent = DataManager.Instance.GetContinent(m_ContinentId);
                continent.Countries.Add(this.Country);
            }
            DataManager.Instance.SaveDataIntoStorage();
            if (OnSaveCompleted != null)
            {
                OnSaveCompleted(false);
            }
        }

        public void Cancel()
        {
        }

        public event OperationCompletedDelegate OnSaveCompleted;

        #endregion
    }
}

By viewing downloads associated with this article you agree to the Terms of Service and the article's licence.

If a file you wish to view isn't highlighted, and is a text file (not binary), please let us know and we'll add colourisation support for it.

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


Written By
Software Developer
Israel Israel
Software Developer in a promising Clean-Tech company

Comments and Discussions