Click here to Skip to main content
Click here to Skip to main content
Add your own
alternative version

Switching to MVVM

, 19 May 2011
How to incorporate MVVM in your existing codebase, step by step, and the risks involved in each step.
MVVM_Src.zip
MVVM
MVVM
Properties
Settings.settings
Step1
Properties
Settings.settings
Step10
Properties
Settings.settings
Step2
Properties
Settings.settings
Step3
Properties
Settings.settings
Step4
Properties
Settings.settings
Step5
Properties
Settings.settings
Step6
Properties
Settings.settings
Step7
Properties
Settings.settings
Step8
Properties
Settings.settings
Step9
Properties
Settings.settings
using System;
using System.Collections.ObjectModel;
using System.Windows;
using System.Windows.Input;
using System.Windows.Controls;

namespace Step8
{
    /// <summary>
    /// Interaction logic for MainWindow.xaml
    /// </summary>
    public partial class MainWindow : Window
    {
        public static DependencyProperty PrincipleProperty =
            DependencyProperty.Register("Principle", typeof(double), typeof(MainWindow));

        public double Principle
        {
            get { return (double)GetValue(PrincipleProperty); }
            set { SetValue(PrincipleProperty, value); }
        }

        public static DependencyProperty InterestRateProperty =
            DependencyProperty.Register("InterestRate", typeof(double), typeof(MainWindow));

        public double InterestRate
        {
            get { return (double)GetValue(InterestRateProperty); }
            set { SetValue(InterestRateProperty, value); }
        }

        public static DependencyProperty DurationProperty =
            DependencyProperty.Register("Duration", typeof(int), typeof(MainWindow));

        public int Duration
        {
            get { return (int)GetValue(DurationProperty); }
            set { SetValue(DurationProperty, value); }
        }

        public static DependencyProperty PaymentProperty =
            DependencyProperty.Register("Payment", typeof(double), typeof(MainWindow));

        public double Payment
        {
            get { return (double)GetValue(PaymentProperty); }
            set { SetValue(PaymentProperty, value); }
        }

        private ObservableCollection<PaymentInfo> payments = new ObservableCollection<PaymentInfo>();

        public ICommand ExitCommand
        { get; set; }

        public ICommand CalculateAmortizationCommand
        { get; set; }

        public MainWindow()
        {
            InitializeComponent();

            ExitCommand = new MyCommand(Close);
            CalculateAmortizationCommand = new MyCommand(CalculatePayment);

            DataContext = this;
        }

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

            Title = "Amortization Schedule for " +
                Convert.ToString(totalpayments) + " Payments";

            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)

Share

About the Author

Zeeshan Amjad
Software Developer (Senior) Bloomberg LP
United States United States
Working as a Sr C++ Developer at Bloomberg LP

| Advertise | Privacy | Mobile
Web04 | 2.8.140823.1 | Last Updated 19 May 2011
Article Copyright 2011 by Zeeshan Amjad
Everything else Copyright © CodeProject, 1999-2014
Terms of Service
Layout: fixed | fluid