Click here to Skip to main content
15,884,237 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.4K   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 System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Shapes;

using GeographicRepresentation.Interfaces;
using GeographicRepresentation.Lib;

namespace GeographicRepresentation.UILib.View
{
    /// <summary>
    /// Interaction logic for EditCountryWindow.xaml
    /// </summary>
    public partial class EditCountryWindow : Window
    {
        #region Members

        Guid m_Id;
        bool m_bNew;
        IEditableCountryViewModel m_DataContext;

        public static RoutedUICommand cmd_SaveCountry = new RoutedUICommand("saveCountry", "saveCountry", typeof(EditCountryWindow));
        public static RoutedUICommand cmd_Cancel = new RoutedUICommand("cancelCountry", "cancelCountry", typeof(EditCountryWindow));

        #endregion

        #region Methods

        #region Ctor        
        
        /// <summary>
        /// Default Ctor
        /// </summary>
        /// <param name="bNew">a flag which determines if the purpose of the window is to create a new country or to edit an
        ///                    existing one</param>
        /// <param name="id">the id - continent if new, country if edit</param>
        public EditCountryWindow(bool bNew, Guid id)
        {
            m_bNew = bNew;
            m_Id = id;
            InitializeComponent();
        }
        

        #endregion

        private void Window_Loaded(object sender, RoutedEventArgs e)
        {
            SimpleOperationDelegate delg = new SimpleOperationDelegate(this.GetDataContext);
            delg.BeginInvoke(new AsyncCallback(this.DataContextLoaded), delg);

            if (m_bNew)
            {
                this.Title = "Add country";
            }

            CommandBinding cb = new CommandBinding(cmd_SaveCountry, onSave, canSave);
            CommandBindings.Add(cb);
            cb = new CommandBinding(cmd_Cancel, onCancel, canCancel);
            CommandBindings.Add(cb);
        }

        /// <summary>
        /// A request for the data context
        /// </summary>
        private void GetDataContext()
        {
            if (m_bNew)
            {
                m_DataContext = InterfacesFactory.Instance.GetEditableCountryViewModelForAdd(m_Id);
            }
            else
            {
                m_DataContext = InterfacesFactory.Instance.GetEditableCountryViewModelForEdit(m_Id);
            }
        }

        /// <summary>
        /// The data context call back. Make all the adjustments in the main thread, using the dispatcher
        /// </summary>
        /// <param name="result"></param>
        private void DataContextLoaded(IAsyncResult result)
        {
            System.Windows.Application.Current.Dispatcher.BeginInvoke(new AsyncCallback(this.DataContextLoadedInMainThread), result);
        }

        /// <summary>
        /// Update the view
        /// </summary>
        /// <param name="result"></param>
        private void DataContextLoadedInMainThread(IAsyncResult result)
        {
            if (result.IsCompleted)
            {
                this.DataContext = m_DataContext;
                SimpleOperationDelegate delg = result.AsyncState as SimpleOperationDelegate;
                delg.EndInvoke(result);
                Button saveButton = (Button)this.Template.FindName("saveButton", this);
                if (saveButton != null)
                {
                    saveButton.Command = EditCountryWindow.cmd_SaveCountry;
                }
                Button cancelButton = (Button)this.Template.FindName("cancelButton", this);
                if (cancelButton != null)
                {
                    cancelButton.Command = EditCountryWindow.cmd_Cancel;
                }
                if (!m_bNew)
                {
                    this.Title = string.Format("Edit {0}", m_DataContext.CountryName);
                }
            }
        }

        private void onSave(object sender, ExecutedRoutedEventArgs args)
        {
            this.Cursor = Cursors.Wait;
            SimpleOperationDelegate delg = new SimpleOperationDelegate(this.SaveOperation);
            delg.BeginInvoke(this.OperationCompleted, delg);
        }

        /// <summary>
        /// Textual data validation
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="args"></param>
        private void canSave(object sender, CanExecuteRoutedEventArgs args)
        {
            int n;
            float f;
            args.CanExecute = txtName.Text.Length > 0 &&
                              int.TryParse(txtSize.Text, out n) &&
                              float.TryParse(txtBirthRate.Text, out f) &&
                              n > 0 && f > 0;
        }

        private void SaveOperation()
        {
            m_DataContext.Save();
        }

        /// <summary>
        /// The save call back. Call the dispatcher to update the view from the main thread
        /// </summary>
        /// <param name="result"></param>
        private void OperationCompleted(IAsyncResult result)
        {
            System.Windows.Application.Current.Dispatcher.BeginInvoke(new AsyncCallback(this.EndOperation), result);
        }

        /// <summary>
        /// End the asynchronos call
        /// </summary>
        /// <param name="result"></param>
        private void EndOperation(IAsyncResult result)
        {
            this.Cursor = Cursors.Arrow;

            SimpleOperationDelegate delg = result.AsyncState as SimpleOperationDelegate;
            delg.EndInvoke(result);
            this.DialogResult = true;
            this.Close();            
        }

        /// <summary>
        /// The cancelation button should run if this is the edit mode, othewise, simply close the window
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="args"></param>
        private void onCancel(object sender, ExecutedRoutedEventArgs args)
        {
            if (!m_bNew)
            {
                this.Cursor = Cursors.Wait;
                SimpleOperationDelegate delg = new SimpleOperationDelegate(this.CancelOperation);
                delg.BeginInvoke(this.OperationCompleted, delg);
            }
            else
            {
                this.Close();
            }
        }

        private void canCancel(object sender, CanExecuteRoutedEventArgs args)
        {
            args.CanExecute = true;
        }

        private void CancelOperation()
        {
            m_DataContext.Cancel();
        }

        #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