Click here to Skip to main content
15,885,216 members
Articles / Programming Languages / C#

Switching to MVVM

Rate me:
Please Sign up or sign in to vote.
4.93/5 (12 votes)
19 May 2011CPOL11 min read 54.4K   1.2K   36  
How to incorporate MVVM in your existing codebase, step by step, and the risks involved in each step.
using System;
using System.Collections.ObjectModel;
using System.ComponentModel;
using System.Windows;
using System.Windows.Input;
using System.Windows.Controls;

namespace Step10
{
    /// <summary>
    /// Interaction logic for MainWindow.xaml
    /// </summary>
    public partial class MainWindow : Window
    {
        private MyViewModel vm = new MyViewModel();

        public MainWindow()
        {
            InitializeComponent();

            vm.RequestClose += delegate
            {
                Close();
            };

            DataContext = vm;
        }
    }

    public abstract class ViewModelBase : INotifyPropertyChanged
    {
        public event EventHandler RequestClose;

        public ICommand ExitCommand
        { get; set; }

        public void Close()
        {
            EventHandler handler = this.RequestClose;

            if (handler != null)
            {
                handler(this, EventArgs.Empty);
            }        
        }

        public void RaisePropertyChanged(string propertyName)
        {
            PropertyChangedEventHandler handler = PropertyChanged;

            if (handler != null)
            {
                handler(this, new PropertyChangedEventArgs(propertyName));
            }
        }

        public event PropertyChangedEventHandler PropertyChanged;
    }

    public class MyViewModel : ViewModelBase
    {
        public double principle;
        public double interestRate;
        public int duration;
        public double payment;

        public double Principle
        {
            get { return principle; }
            set
            {
                principle = value;
                RaisePropertyChanged("Principle");
            }
        }

        public double InterestRate
        {
            get { return interestRate; }
            set
            {
                interestRate = value;
                RaisePropertyChanged("InterestRate");
            }
        }

        public int Duration
        {
            get { return duration; }
            set
            {
                duration = value;
                RaisePropertyChanged("Duration");
            }
        }

        public double Payment
        {
            get { return payment; }
            set
            {
                payment = value;
                RaisePropertyChanged("Payment");
            }
        }

        public ObservableCollection<PaymentInfo> Payments
        { get; set; }

        public ICommand CalculateAmortizationCommand
        { get; set; }

        public MyViewModel()
        {
            CalculateAmortizationCommand = new MyCommand(CalculatePayment);
            ExitCommand = new MyCommand(Close);

            Payments = new ObservableCollection<PaymentInfo>();
        }

        // Calculate the complete amortization schedule and fill the list control
        private void CalculatePayment()
        {
            int totalpayments = Duration * 12;

            double monthlyInterest = CalculateMonthlyInterest(InterestRate);

            // calculate interest term
            double interestTerm = Math.Pow((1 + monthlyInterest), totalpayments);

            // calculate payment
            Payment = (Principle * monthlyInterest) / (1 - (1 / interestTerm));

            Payments.Clear();

            for (int iIndex = 1; iIndex <= totalpayments; ++iIndex)
            {
                PaymentInfo paymentInfo = new PaymentInfo();
                paymentInfo.PaymentNo = iIndex;
                paymentInfo.Balance = CalculateBalance(iIndex);
                paymentInfo.Payment = Payment;
                paymentInfo.Interest = CalculateInterestPart(iIndex);
                paymentInfo.Principle = CalculatePrinciple(iIndex);

                Payments.Add(paymentInfo);
            }

            //lstAmortization.ItemsSource = payments;
        }

        // Calculate the remaining balance at particular payment
        private double CalculateBalance(int month)
        {
            double monthlyInterest = CalculateMonthlyInterest(InterestRate);

            double interestTerm = Math.Pow((1 + monthlyInterest), month);
            double totalInterest = Principle * interestTerm;
            double totalPaid = Payment * (interestTerm - 1) / monthlyInterest;
            return totalInterest - totalPaid;
        }

        // Calculate the Interest part of any particular payment
        private double CalculateInterestPart(int month)
        {
            double monthlyInterest = CalculateMonthlyInterest(InterestRate);

            double interestTerm = Math.Pow((1 + monthlyInterest), (month - 1));
            double totalInterest = Principle * interestTerm;
            double totalPaid = Payment * (interestTerm - 1) / monthlyInterest;
            return (totalInterest - totalPaid) * monthlyInterest;
        }

        // Calculate the principle part of any particular payment
        private double CalculatePrinciple(int month)
        {
            return Payment - CalculateInterestPart(month);
        }

        // Calculate the monthly interest rate
        private double CalculateMonthlyInterest(double InterestRate)
        {
            double monthlyInterest = InterestRate;
            monthlyInterest /= 100;
            monthlyInterest /= 12;

            return monthlyInterest;
        }
    }

    public class PaymentInfo
    {
        public int PaymentNo
        { get; set; }

        public double Payment
        { get; set; }

        public double Principle
        { get; set; }

        public double Interest
        { get; set; }

        public double Balance
        { get; set; }
    }

    public class MyValidation : ValidationRule
    {
        public override ValidationResult Validate(object value, System.Globalization.CultureInfo cultureInfo)
        {
            int number = Int32.Parse((string)value);

            if (number < 0)
            {
                return new ValidationResult(false, "Please enter values greater than zero.");
            }

            return new ValidationResult(true, null);
        }
    }

    public class MyCommand : ICommand
    {
        public Action Function
        { get; set; }

        public MyCommand()
        {
        }

        public MyCommand(Action function)
        {
            Function = function;
        }

        public bool CanExecute(object parameter)
        {
            if (Function != null)
            {
                return true;
            }

            return false;
        }

        public void Execute(object parameter)
        {
            if (Function != null)
            {
                Function();
            }
        }

        public event EventHandler CanExecuteChanged
        {
            add { CommandManager.RequerySuggested += value; }
            remove { CommandManager.RequerySuggested -= value; }
        }
    }
}

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
Team Leader American Institute for Research
United States United States
Working as a Team leader in American Institute for Research

Comments and Discussions