Monday, October 10, 2011

Threading and Saving Data with LINQ to SQL

In our last post we looked at the actual calculations of the amortization.

Threading

Depending on the machine and the values the user has specified the calculation and displaying of the mortgage could lag. 100-200 milliseconds is the threshold before a user notices lag. We want the transition from MortgageHome Page to MortgageReport Page to be as seamless as possible while still immediately amortizing the mortgage. In order to accomplish this we need to run the calculations in their own worker thread, outside the UI thread.

In the MortgageReport page we set up the following threading.
//start a worker thread so it does not bog down the gui
private void Amortize()
{
    BackgroundWorker worker = new BackgroundWorker();

    worker.DoWork += delegate(object s, DoWorkEventArgs args) 
    {
        args.Result = RunAmortize(); 
    }; 
    worker.RunWorkerCompleted += delegate(object s, 
        RunWorkerCompletedEventArgs args) 
    {
        theMI = (MonthIteration)args.Result;
        SetGridData();
    }; 
    worker.RunWorkerAsync();
}

private MonthIteration RunAmortize()
{
    MonthIteration thisMI = new MonthIteration(m);
    return thisMI;
}
In the last post we saw how the MonthIteration class constructor ran all of our calculations for us. As soon as the first line in RunAmortize is complete so are our calculations.

I choose a BackgroundWorker due to it's straight forward approach of assignment to clearly spelled out events. In this case we are creating 2 anonymous delegates; one to start the thread and do the work and one to notify the thread that the work is complete. There are other events for updating progress and when dispose on the component is called. This could have easily just been pulled into its own class. However, since it's relatively uninvolved I kept it in the MortgageReport Page.

Saving Data with LINQ to SQL

The last piece of the puzzle is to save the data to the database for use later on. Because we put the legwork in for LINQ to SQL in a previous post, all we need to do now is use that code to save the data.
private bool IsValid(ref String em, bool checkForName)
{
    List<String> errors = new List<string>();

    if (checkForName && m.Name == null)
        errors.Add("You must specify a Name.");
    else if (checkForName && m.Name.Trim() == String.Empty)
        errors.Add("You must specify a Name.");
    if (m.Principal <= 0)
        errors.Add("You must specify Principal Amount greater than $0.00.");
    if (m.Term <= 0)
        errors.Add("You must specify a Loan Term greater than 0.");
    if (m.InterestRate <= 0)
        errors.Add("You must specify an Interest Rate.");
    em = String.Join(Environment.NewLine, errors);

    if (errors.Count > 0)
        return false;
    else
        return true;
}

Before we can even attempt to save we need to validate all the necessary values. In this case we pass in a string by ref to ensure the calling method can show the user the problems encountered.
private void SaveB_Click(object sender, RoutedEventArgs e)
{
    String em = "";
    if (!IsValid(ref em, true))
    {
        MessageBoxResult result = MessageBox.Show((Window)this.Parent, 
            em, "Error", MessageBoxButton.OK, MessageBoxImage.Error);
    }
    else
    {
        m.Date = DateTime.Now;

        if (isNew)
        {
            if (DBApi.DB.mortDB.Mortgage.Count() > 0)
            {
                m.Key = (from thisMort in DBApi.DB.mortDB.Mortgage
                            select thisMort.Key).Max() + 1; 
            }
            else
                m.Key = 0;
            DBApi.DB.mortDB.Mortgage.InsertOnSubmit(m);
        }

        DBApi.DB.mortDB.SubmitChanges();
        isNew = false;
    }
}

If the values are invalid we give the user immediate feedback in the form a error MessageBox.

One problem that crept up on me when I was working on this is the defaulting of the Key to 0. Since Key 0 already exists in the database, we are now no longer allowed to add new records. To get around this I simply did a quick LINQ to SQL query to find the Max Key and incremented it by 1.

InsertOnSubmit is the same as the insert command in T-SQL. SubmitChanges looks for updates, inserts or deletions and sends them to the database.

That's it! We now have a fully functional Mortgage Calculator that looks pleasant, is somewhat dynamic to the users preferences, stores UI state and gives the user a lot of useful information.

Future Improvements

When coding it's almost impossible to not notice improvements. The following are some features I would like to see in the Mortgage Calculator in the future.
  1. An installer package
  2. In-grid adjustments
  3. Better color schema
  4. More detailed stats on values such as
    1. Total insurance paid
    2. Total taxes paid
  5. Home page selection memory
  6. Years and months term input fields instead of just months
  7. PMI
  8. Date tracking by listing the start date
  9. Monthly payment date to adjust interest and principal to the day payment was received
  10. Application Icon
  11. MortgageHome showing more details about each Mortgage
  12. Start amortizing in the middle of the year and figure costs accordingly like Tax increasing at the end of the year, which might be 4 months into the loan.
  13. Graphs and charts
  14. User accounts
  15. User account summaries of the user's entire portfolio

Download the Code Here

Mortgage Logic

In the last post we dealt with storing the state of the GUI and loading the grid with data.

Amortizing

The most difficult thing about amortizing the mortgage is figuring out what data is most useful to the user.

In a previous post I listed the values I would like to track.
  • Principal
  • Interest
  • Extra Payments
  • Balance
  • Home Value
  • Tax
  • Insurance
  • Association Dues
  • Maintenance
  • Total Monthly Cost
  • Equity
  • Loan To Value
  • Rental Income
  • Cash Flow
  • Tax Appreciation
  • Insurance Appreciation
  • Association Dues Appreciation
  • Maintenance Appreciation
  • Rent Appreciation
  • Home Value Appreciation

The task was to create a structure to store all of this data, one month at a time. I created MonthIteration with all the variables I would show to the user.

private int _PaymentNum;
public String PaymentNum
{
    get
    {
        return _PaymentNum.ToString();
    }
}
...
private decimal _CashFlow;
public String CashFlow
{
    get
    {
        return _CashFlow.ToString("C2");
    }
}
MonthIteration has public string properties that represent the underlying data. This allows for formatting of the values and feeding the DataGridTextColumns strings instead of something it doesn't know how to process.

We also have a list of static variables. These are not displayed to the user on a month-by-month basis and do not change every month.

//the following varibles do not change ever iteration 
//and are never displayed to the user
private static decimal YearlyMaintenance;
private static decimal YearlyTax;
private static decimal YearlyInsurance;
private static decimal monthlyHoueValueIncrease;
private static decimal monthlyInterestRate;

//The Appreciation values never change and
//we wanted to forgo the double conversion at each iteration
private static decimal HouseValueApp;
private static decimal RentApp;
private static decimal MaintenanceApp;
private static decimal TaxesApp;
private static decimal InsuranceApp;
private static decimal AssociationDuesApp;

//if the check box is not selected we do not
//factor in the amounts into the totals.
private static bool HomeValueShowDef;
private static bool InsuranceShowDef;
private static bool MaintenanceShowDef;
private static bool PropertyTaxShowDef;
private static bool RentShowDef;
private static bool AssociationDuesShowDef;

//cumlative total of all interest payed
private static decimal TotalInterest;
private static decimal BeginingPrincipal;
We have one more static variable that holds all of the MonthIterations created.
private static List<MonthIteration> allIterations;
I wanted a simple class where I passed in as few variables as possible and returned a result without over complicating the class implementation. I created 2 constructors; a public one to load with the initial values and a private one for all consecutive iterations.
//this constructor is used for the first iteration
public MonthIteration(Mortgage inMortgage)
{
    allIterations = new List<MonthIteration>();
    allIterations.Add(this);

    LoadTheMortgageValues(inMortgage);

    //start from payment 1
    _PaymentNum = 1;
    _NumOfPayments = 1;

    //we want to keep track of all interest payed 
    //through the life of the loan
    TotalInterest = 0;

    monthlyHoueValueIncrease = 
        Math.Round(((_HouseValue * HouseValueApp) / 12), 2);

    //The first thing to do is calculate the payment
    _Payment = CalculateMonthlyPayment(inMortgage);
    _Payment = Math.Round(_Payment, 2);


    CalculateThisIteration();
}
        
//all subsequent iterations are called from the 
//previous iteration using this constructor
private MonthIteration(MonthIteration lastIteration)
{
    allIterations.Add(this);

    //load the values from the last iteration
    _PaymentNum = lastIteration._PaymentNum + 1;
    _NumOfPayments++;
    _Balance = lastIteration._Balance;
    _HouseValue = lastIteration._HouseValue;
    _RentCharged = lastIteration._RentCharged;
    _AssociationDues = lastIteration._AssociationDues;

    //_PaymentNum+1 is 1 based so we should update on the 13th payment
    if ((_PaymentNum-1) % 12 == 0)
    {   // = Math.Round(_Payment, 2);
        monthlyHoueValueIncrease = 
            Math.Round(((_HouseValue * HouseValueApp) / 12), 2);
        _RentCharged = Math.Round(_RentCharged * (1 + RentApp), 2);
        YearlyMaintenance = 
            Math.Round(YearlyMaintenance * (1 + MaintenanceApp), 2);
        YearlyTax = Math.Round(YearlyTax * (1 + TaxesApp), 2);
        YearlyInsurance = 
            Math.Round(YearlyInsurance * (1 + InsuranceApp), 2);
        _AssociationDues = 
            Math.Round(_AssociationDues * (1 + AssociationDuesApp), 2);
    }

    CalculateThisIteration();
}
In the Public constructor we pass in the Mortgage object which contains all the user inputted values and copy's them into the local variables in the LoadTheMortgageValues method. We then default some values, find out the monthly payment and calculate this month by calling CalculateThisIteration.

Calculating the monthly mortgage payment is straight forward.
//Loan equation
private decimal CalculateMonthlyPayment(Mortgage inMortgage)
{
    //c = monthly payment
    //r = interest rate
    //n = number or months
    //p = principal

    //c = (r/(1-(1+r)^(-n))) * p

    monthlyInterestRate = inMortgage.InterestRate / 12;
    double onePlusI = 1 + (double)monthlyInterestRate;
    double bottomToBeMinusedFrom = Math.Pow(onePlusI, (-1 * (inMortgage.Term)));
    decimal bottom = (decimal)(1 - bottomToBeMinusedFrom);
    decimal everyThingExceptPrincipal = monthlyInterestRate / bottom;
    decimal thePayment = _Balance * everyThingExceptPrincipal;
    return thePayment;
}
CalculateThisIteration is just book keeping.

//Update the displayed values
private void CalculateThisIteration()
{
    //The basic calculations
    _Interest = Math.Round(monthlyInterestRate * _Balance, 2);
    _Principal = _Payment - _Interest;
    _Balance = _Balance - (_Principal + _ExtraPayment);
    _HouseValue = _HouseValue + monthlyHoueValueIncrease;

    //add the interest payed
    TotalInterest += _Interest;

    //grab the monthly tax, insurance and maintenance
    _Tax = Math.Round(YearlyTax / 12, 2);
    _Insurance = Math.Round(YearlyInsurance / 12, 2);
    _Maintenance = Math.Round(YearlyMaintenance / 12, 2);

    //Investment data points
    _Equity = _HouseValue - _Principal;
    _TotalCost = _Payment + _ExtraPayment;
    if (PropertyTaxShowDef)
        _TotalCost += _Tax;
    if (MaintenanceShowDef)
        _TotalCost += _Maintenance;
    if (InsuranceShowDef)
        _TotalCost += _Insurance;
    if (AssociationDuesShowDef)
        _TotalCost += _AssociationDues;
    _CashFlow = _RentCharged - _TotalCost;

    //we don't want to show an Infinity value by dividing by 0
    if (_HouseValue == 0)
        _LoanToValue = 0;
    else
        _LoanToValue = _Balance / _HouseValue;

    //we have to have at least 1 penny to iterate another month
    if (_Balance <= ((decimal)0.009))
        return;

    MonthIteration mi = new MonthIteration(this);
}
At the end of CalculateThisIteration we now create the next iteration if the balance >= $0.01.

In the next post we are going to be dealing with Threading and Saving Data with LINQ to SQL.


Download the Code Here

Sunday, October 9, 2011

Mortgage Report XMAL Stored State and DataGrid

In the last post we covered validation with data binding and converters.

Overview of Goals for Usability

When I first started working on this project in WPF I had a short list of GUI guidelines I wanted to adhere to:
  1. Better overall use of space
  2. Uniform spacing and orientation of user input fields
  3. Ability to hide most optional fields
  4. Ability to hide optional columns in the Amortization Schedule
With WPF and a small amount of research you practically fall into the first 2 objectives.

Ability to Hide Most Optional Fields

WPF was well thought out. Somewhere along the line someone working on WPF realized that binding should not stop just at values but could be extended to attributes and states in GUI components.

I wanted the Expander components in my MortgageReport Page to be open or closed based upon their previous state when the last save of the Mortgage objects occurred.

In a previous post I showed the Mortgage table in our database. It contained a bunch of expand bit typed columns. These would save whether or not an Expander was expanded.

Lets take a look at one of the Expanders in xaml:
<Expander Header="Home Value" HorizontalAlignment="Left" 
    Name="homeValueE" VerticalAlignment="Top" Width="225" 
    Grid.Row="3" IsExpanded="{Binding Path=HomeValueExpand}">
...
</Expander>
IsExpanded="{Binding Path=HomeValueExpand}" tells Expander to bind to the HomeValueExpand property in the Mortgage object. Dead simple.

Ability to hide optional columns in the Amortization Schedule

Hiding columns in a grid was a little more difficult although not much.

WPF has Visual Trees and Logical Trees to represent the UI. The Logical Tree contains all UI components specified in xaml or programmatically generated. The Visual Tree contains only components that need to be rendered and inherit from the Visual or Visual3D classes.

<DataGrid Grid.Column="0" Grid.Row="0" Name="amortizeGrid" 
    CanUserResizeRows="False" CanUserSortColumns="False" 
    CanUserReorderColumns="False" AutoGenerateColumns="False" 
    SelectionMode="Single" AlternatingRowBackground="Beige" Margin="10,0" 
    BorderThickness="1" FontWeight="Normal" IsReadOnly="True">
    <DataGrid.ColumnHeaderStyle>
        <Style TargetType="Control">
            <Setter Property="FontWeight" Value="Bold"/>
        </Style>
    </DataGrid.ColumnHeaderStyle>
    <DataGrid.Columns>
        <DataGridTextColumn Binding="{Binding PaymentNum}" Header="Payment #" />
        ...
        <DataGridTextColumn Binding="{Binding CashFlow}" Header="Cash Flow" />
    </DataGrid.Columns>
</DataGrid>
While DataGrid is in the Visual Tree, DataGridColumns (a base class for DataGridTextColumns) is not. Therefore, binding to a property that modifies the visual appearence does not work.

The way I got around this was to hide or show columns in the DataGrid programmatically.

private void SetColumnsVisible()
{
    BooleanToVisibilityConverter btvc = new BooleanToVisibilityConverter();

    //we hate magic numbers
    amortizeGrid.Columns[GridConstants.AMORTIZE_GRID_TAX_COL].Visibility = 
        (System.Windows.Visibility)btvc.Convert(m.PropertyTaxShowDef, 
        null, null, null);
...
    amortizeGrid.Columns[GridConstants.AMORTIZE_GRID_CASHFLOW_COL].Visibility = 
        (System.Windows.Visibility)btvc.Convert(m.RentShowDef, 
        null, null, null);
}
Because Visibility is not a boolean property but an enum of Collapsed, Hidden or Visible, we need something to convert our bit/boolean values to Hidden or Visible. BooleanToVisibilityConverter is a class found Windows.Controls that does the conversion for you.

I hate magic numbers with the fury of a thousand suns. Nothing is more annoying then trying to keep straight what numbers represent when you have 50 other things to think about. What's more, what happens when the columns now represent something else? Using constants solves both of these problems, hence the GridConstants.

Loading Data into the Grid and Summary Data

Since binding is an amazingly effective tool in WPF I wanted to use it again for displaying the results of the Amortization logic. After the calculations are complete we receive a list of MonthIteration objects (we will cover its contents more in the next post). The MonthIteration class contains all the data that needs to be displayed in the Grid.

MonthIteration has public string properties that represent the underlying data. This allows for formatting of the values and feeding the DataGridTextColumns strings instead of something it doesn't know how to process.

private int _PaymentNum;
public String PaymentNum
{
    get
    {
        return _PaymentNum.ToString();
    }
}
...
private decimal _CashFlow;
public String CashFlow
{
    get
    {
        return _CashFlow.ToString("C2");
    }
}
If we look at our DataGrid code again we notice that the individual columns are bound.

<DataGrid Grid.Column="0" Grid.Row="0" Name="amortizeGrid" 
    CanUserResizeRows="False" CanUserSortColumns="False" 
    CanUserReorderColumns="False" AutoGenerateColumns="False" 
    SelectionMode="Single" AlternatingRowBackground="Beige" Margin="10,0" 
    BorderThickness="1" FontWeight="Normal" IsReadOnly="True">
    <DataGrid.ColumnHeaderStyle>
        <Style TargetType="Control">
            <Setter Property="FontWeight" Value="Bold"/>
        </Style>
    </DataGrid.ColumnHeaderStyle>
    <DataGrid.Columns>
        <DataGridTextColumn Binding="{Binding PaymentNum}" Header="Payment #" />
        ...
        <DataGridTextColumn Binding="{Binding CashFlow}" Header="Cash Flow" />
    </DataGrid.Columns>
</DataGrid>
The code that binds the list of MonthIteration to the DataGrid is shown below.
private void SetGridData()
{
    amortizeGrid.ItemsSource = theMI.ReturnAllIterations();
    totalInterestPaidL.Text = theMI.TotalInterestPaid;
    totalPaidL.Text = theMI.TotalInterestPrincipalPaid;
    int numOfMonths = theMI.NumOfPayments;
    int numOfYears = numOfMonths / 12;
    numOfMonths = numOfMonths % 12;
    loanTermL.Text = numOfYears.ToString() + " years " + 
        numOfMonths.ToString() + " month(s)";
    totalCostL.Text = theMI.Payment;
}
In a lot of Mortgage applications a summary of interesting facts about the mortgage is displayed to the user. The rest of the SetGridData method is just a summary of details I think might be helpful to the user.













13 years 4 months is a rather odd length for a mortgage. This is due to the implementation of my Extra Payment field shortening the length of the loan.















Each month the user stipulated paying an extra $321.00. This cut the mortgage time down by more then half. Having the summary information at the top is a nice way around scrolling to the bottom of the amortization and dividing by 12.

In our next post we will go more in depth with the amortization calculations.


Download the Code Here

Validation in the Mortgage Report Page

In the last post we covered data context and data binding in the MortgageReport Page.

Validation with Data Binding

In a previous post we discussed LINQ to SQL and explored our Database, data model and the DataContext generated by SQL Metal.

Now that we have a solid foundation of how binding works lets try to extend it's functionality.

<TextBox Name="principalT" Grid.Row="1" Text="{Binding Path=Principal, ValidatesOnDataErrors=True,  Converter={StaticResource currencyConverter}}" />
We can see that this TextBox is bound to the Principal property located inside the Mortgage object. The Text attribute also contains two other interesting properties.

ValidatesOnDataError lets the GUI component know that it has to check the Model object bound to the control for errors.

This is our validation logic on the Model:

partial void OnPrincipalChanging(decimal value)
{
    if(value <= 0)
        AddError("Principal", "Principal must be greater than 0.");
    else
        RemoveError("Principal", "Principal must be greater than 0.");
}
In our case we have a special setting for all TextBox's that modifies the look if errors have been encountered. We've placed it in the App.xaml file.

<Style TargetType="{x:Type TextBox}">
    <Setter Property="Validation.ErrorTemplate">
        <Setter.Value>
            <ControlTemplate>
                <DockPanel LastChildFill="True">
                    <TextBlock DockPanel.Dock="Top" FontSize="12pt">
                        *
                    </TextBlock>
                    <Border BorderBrush="Red" BorderThickness="1">
                        <AdornedElementPlaceholder />
                    </Border>
                </DockPanel>
            </ControlTemplate>
        </Setter.Value>
    </Setter>
    <Style.Triggers>
        <Trigger Property="Validation.HasError" Value="true">
            <Setter Property="ToolTip"
        Value="{Binding RelativeSource={RelativeSource Self}, 
                Path=(Validation.Errors)[0].ErrorContent}"/>
        </Trigger>
    </Style.Triggers>
</Style>
Validation.ErrorTemplate specifies that this template should be applied when errors are encountered. In this case, we show a red border and an asterisk. We also change the ToolTip to show the error message returned from the Model validation.

Lets take a look at the result when invalid data is entered.









Converters

Converter={StaticResource currencyConverter} specifies how to convert from the data stored in the model to a string displayed in the TextBox and back.

However, We have a class called "CurrencyConverter," but not "currencyConverter." "currencyConverter" is specified at the top of the xaml file in the Page.Resources section.

<Page.Resources>
    <l:CurrencyConverter x:Key="currencyConverter" />
    <l:PercentageConverter x:Key="percentageConverter" />
    <BooleanToVisibilityConverter x:Key="BooleanToVisibilityConverter"/>
    <Style x:Key="vStyle" TargetType="{x:Type DataGridCell}">
        <Setter Property="Visibility" Value="{Binding 
            YourObjectVisibilityProperty}"/>
    </Style>
</Page.Resources>
One more step is required. We need to make sure there is a reference to the namespace where the converters lie. "l" reffers to the the xml namespace attribute in the Page tag at the top of the file.
<Page x:Class="MortCalc.MortgageReportPage"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:l="clr-namespace:MortCalc.Converters"
        xmlns:j="clr-namespace:MortCalc.AmortizeLogic"
        Title="Mortgage Calculator" HorizontalAlignment="Stretch" VerticalAlignment="Stretch">
Let's take a look at our currency converter:
namespace MortCalc.Converters
{
    [ValueConversion(typeof(decimal), typeof(string))]
    public class CurrencyConverter : IValueConverter
    {
        public object Convert(object value, Type targetType, 
            object parameter, CultureInfo culture)
        {
            if (value == null)
                return 0;
            else
                return ((decimal)value).ToString("C2", culture);
        }

        public object ConvertBack(object value, Type targetType, 
            object parameter, CultureInfo culture)
        {
            if (value.ToString().Trim() == "")
                return 0;

            decimal result;
            decimal.TryParse(value.ToString(), NumberStyles.Currency, 
                culture, out result);
            return result;
        }
    }
}
Convert takes the decimal value and uses the ToString method, passing in the "C2" format, to retrieve a currency formatted in the passed in culture with an after decimal precision of 2. ConvertBack does the opposite using the TryParse method.

Using the converter for currency changes 20.3 to $20.30.

Likewise, I wanted the percentage rate to be human readable but stored in a format immediately usable in mortgage calculations. Something obtuse like .0675 gets converted to 6.75.

In the next post we will dive back into the MortgageReport Page xmal and take a look at the DataGrid.


Download the Code Here

DataContext on the Mortgage Report Page

In the last post we covered retrieving and showing existing Mortgage Names.

In this post we will be dealing with more data binding and some user input.

Mortgage Report Page

The MortgageReport Page serves 2 main purposes:
  1. Allow the user to specify and save the details of a Mortgage
  2. Amortize the Mortgage



































































Compare this new GUI with the old one and we can see a clear difference.

















More space is now allocated to the actual amortization of the loan. The input fields are minority of the page and properties the user is not interested in can be minimized. On top of the cosmetic improvement I had spent less time laying out and designing the GUI in WPF. With windows forms, any time I decided to add a new feature, rearranging the input fields would become a tedious rush of shuffling and resizing input fields. Now it's as simple as adding a few lines of xaml to an existing Panel tag.

In a previous post we listed all of the details we wanted to track during the Amortization.
  • Principal
  • Interest
  • Extra Payments
  • Balance
  • Home Value
  • Tax
  • Insurance
  • Association Dues
  • Maintenance
  • Total Monthly Cost
  • Equity
  • Loan To Value
  • Rental Income
  • Cash Flow
  • Tax Appreciation
  • Insurance Appreciation
  • Association Dues Appreciation
  • Maintenance Appreciation
  • Rent Appreciation
  • Home Value Appreciation

Notice that most of these values are shown in the MortgageReportPage. Equity, Loan to Value, Cash Flow and Total Monthly Cost are missing from the Left hand side. This is due to these values being the result of the other values being operated on.

Data Binding

Lets take a look at the code behind.
public MortgageReportPage(bool inIsNew = true)
{
    InitializeComponent();
    isNew = inIsNew;
    if (inIsNew)
    {
        m = new Mortgage();
        this.DataContext = m;
        SetColumnsVisible();
    }
}

// Custom constructor to pass Mortgage report data
public MortgageReportPage(object data)
    : this(false)
{
    // Bind to the mortgage report data.
    m = (Mortgage)data;
    this.DataContext = m;

    SetColumnsVisible();

    String em = String.Empty;
    if (IsValid(ref em, false))
        Amortize();
}

We have 2 constructors; one takes in a defaulted boolean value, the other takes in the Mortgage object from the Page that called it.

this.DataContext = m;
This is where the Data Binding for all the TextBoxes, CheckBoxes and Expanders originates. The DataContext property of the Page provides access to the bound data for its child components. All the public data in the Mortgage class is now freely available to any Component on the Page.

The last thing we need to do before the data will be automatically loaded into our fields and updated to the Mortgage class is to tell the children components themselves what they should be bound to.
<TextBox Name="nameT" Grid.Row="1" Text="{Binding Path=Name, ValidatesOnDataErrors=True}" />
Text="{Binding Path=Name..." is the final step in binding the Column named "Name" in the Mortgage class to the TextBox nameT in xaml. Simple.

In the next post we will be dealing with validation and converters.


Download the Code Here

DataContext on the Mortgage Home Page

In our last post we covered integrating the database CRUD operations through our MortDB DataContext class. In this post we get to see how simple working with a DataContext can be.

The MortgageHome Page

In a previous post we stopped just short of diving into the MortgageHome.xaml's code behind.



















Here is the code behind:

namespace MortCalc
{
    /// <summary>
    /// Code Behind for MortgageHome.xaml
    /// </summary>
    public partial class MortgageHome : Page
    {

        public MortgageHome()
        {
            InitializeComponent();
        }

        private void Amortize_Button_Click(object sender, RoutedEventArgs e)
        {
            //error message tell them to select a mortgage
            if (mortgageListBox.SelectedItem == null)
            {
                MessageBoxResult result = MessageBox.Show(
                    (Window)Parent, "Please Select a Mortgage.",
                    "Error", MessageBoxButton.OK, 
                    MessageBoxImage.Error);
            } else{
                // View Mortgage Amortization Report
                MortgageReportPage mortgageReportPage = new 
                    MortgageReportPage(mortgageListBox.SelectedItem);
                this.NavigationService.Navigate(mortgageReportPage);
            }
        }

        private void New_Button_Click(object sender, RoutedEventArgs e)
        {
            // View Mortgage Amortization Report
            MortgageReportPage mortgageReportPage = 
                new MortgageReportPage();
            this.NavigationService.Navigate(mortgageReportPage);
        }

        private void Page_Loaded(object sender, RoutedEventArgs e)
        {
            var results = from m in DBApi.DB.mortDB.Mortgage
                            select m;

            mortgageListBox.ItemsSource = results.ToList();
        }
    }
}

When looking at the form there are 3 main things that it needs to accomplish:
  1. Load the Names of the Mortgages
  2. Create a new Mortgage
  3. Amortize a selected Mortgage

Load the Names of the Mortgages

The Mortgage Names are loaded into the Listbox component.

<ListBox Name="mortgageListBox"  DisplayMemberPath="Name" FontSize="18" />
We can see that DisplayMemberPath is set to "Name". "Name" in this context makes little sense.

Name is a property in the Mortgage class. Knowing this we can now make sense of the Page_Loaded event function.
private void Page_Loaded(object sender, RoutedEventArgs e)
{
    var results = from m in DBApi.DB.mortDB.Mortgage
                    select m;

    mortgageListBox.ItemsSource = results.ToList();
}

The LINQ to SQL code:

var results = from m in DBApi.DB.mortDB.Mortgage select m;
is doing a SQL like query from the Mortgage table in our database, in code. This is equivalent to the following T- SQL:
SELECT *
FROM Mortgage
We just avoided creating a connection, sending a query, iterating through a result set, ect...

Now all that's left is to bind the results to the ListBox.

mortgageListBox.ItemsSource = results.ToList();
By binding the data we avoided for loops of loading details into the list box and matching names to objects located globally in the Page class. Data binding is powerful and elegant.

Create a New Mortgage

When the New button is clicked the Click event gets fired per our xaml code.
<Button Grid.Row="0" Grid.Column="0" HorizontalAlignment="Right" Click="New_Button_Click" Style="{StaticResource buttonStyle}">
    New
</Button>
Here is the event click function:

private void New_Button_Click(object sender, RoutedEventArgs e)
{
    // View Mortgage Amortization Report
    MortgageReportPage mortgageReportPage = new MortgageReportPage();
    this.NavigationService.Navigate(mortgageReportPage);
}
All we are doing here is navigating to the new page. We instantiate the Page object and tell our NavigationWindow class to Navigate to it. All specifying and saving of data will take place in this new Page.

Amortize a selected Mortgage

When someone selects an existing Mortgage we need a way to tell the MortgageReportPage which record we are working on.
private void Amortize_Button_Click(object sender, RoutedEventArgs e)
{
    //error message tell them to select a mortgage
    if (mortgageListBox.SelectedItem == null)
    {
        MessageBox.Show((Window)Parent, 
            "Please Select a Mortgage.",
            "Error", MessageBoxButton.OK, MessageBoxImage.Error);
    } else{
        // View Mortgage Amortization Report
        MortgageReportPage mortgageReportPage = new MortgageReportPage
            (mortgageListBox.SelectedItem);
            this.NavigationService.Navigate(mortgageReportPage);
    }
}
Check to make sure they selected something and if not let them know they need to.

The only way this Navigation to the MortgageReportPage differs from the last method is the passing in of the ListBox's selected item. I am not operating on the value at all and I am not casting as a Mortgage. Very Simple.

The next post will be dealing with the MortgageReport Page and how it binds data in the Mortgage class to the GUI components.


Download the Code Here

Saturday, October 8, 2011

Database and CRUD

In the last post we covered some of the Navigation/xaml code and stopped just short of binding data and what the code behind looks like.

I have worked on past projects where CRUD operations were hand coded. This makes sense if you don't have binding. Now that binding, Entity Framework, LINQ to SQL, LINQ to Objects ect... exist hand coding CRUD is a more error prone and a completely antiquated waste of time.

In a previous post we created the database file. In this post we are going to go into integrating the database into our Mortgage Calculator.

SQL Metal

One requirement I had initially for the Database was use of LINQ to SQL. SQL Server Compact supports this. However, there's a catch!

Part of developing LINQ to SQL applications involves modeling the data after the structure of the database. A code file is then generated which contains a DataContext that your application can use to preform CRUD operations on.

Normally, if you are using any other SQL Server database type, in Server Explorer, you simply drag the tables in your project into the dbml file area.

Visual studio doesn't support SQL Server Compact LINQ to SQL DataContext file generation.

This is where SQL Metal comes into play. To generate your DataContext file you have to run the command line utility and specify your database and the output file you would like to generate.
  1. Navigate to sqlmetal.exe
  2. Specify your .sdf file location
  3. Specify your c# file and location you wish to generate.
  4. Run it.
  5. Add the new cs file to your solution.
My Command line statement looked like this:
C:\Program Files (x86)\Microsoft SDKs\Windows\v7.0A\bin>sqlmetal C:\MortCalc\MortCalc\DBApi\MortDB.sdf /code:C:\MortCalc\MortCalc\DBApi\MortDB.cs

DB API

Lets take a look at the DBApi folder:


DB.cs:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace MortCalc.DBApi
{
    static class DB
    {
        public static MortDB mortDB = new MortDB("DBApi\\MortDB.sdf");
    }
}

DB is a static class which contains an instantiation of MortDB. MortDB is itself a DataContext class. I wanted 1 and only 1 instance of MortDB accessible from the whole application. Problems arise if the same DataContext is not used everywhere.

For example: I had 2 different instances of MortDB getting created; one in the Home Page and one in a page where I saved data. When I navigated back to the Home Page the record I had just saved was missing. Having 1 MortDB solved this problem. I also wanted to avoid sending around objects inside the program unnecessarily.


MortDB.cs:

MortDB.cs is the file that SQL Metal generated. It contains the DataContext class MortDB which will handle all the CRUD operations. It also contains the Mortgage class. This is the only model class of the only table in our Database.

Inside of Mortgage all of our table columns have sections of code dedicated to them.

partial void OnPrincipalChanging(decimal value);
partial void OnPrincipalChanged();
...
[Column(Storage="_Principal", DbType="Decimal(18,2) NOT NULL")]
public decimal Principal
{
    get
    {
        return this._Principal;
    }
    set
    {
        if ((this._Principal != value))
        {
            this.OnPrincipalChanging(value);
            this.SendPropertyChanging();
            this._Principal = value;
            this.SendPropertyChanged("Principal");
            this.OnPrincipalChanged();
        }
    }
}

When something sets the property (the binded-to object) the partial unimplemented Changing and Changed methods are called.


MortDB.Helper1.cs:

MortDB.Helper1.cs is my other half of the MortDB.cs partial file implementation.

partial void OnPrincipalChanging(decimal value)
{
    if(value <= 0)
        AddError("Principal", "Principal must be greater than 0.");
    else
        RemoveError("Principal", "Principal must be greater than 0.");
}

I've added my own validation logic for incoming values to adjust errors accordingly.

If I were to add a new column to the Mortgage table I would be forced to regenerate the MortDB.cs file. Because of partial classes and my particular implementation being in a separate file, I don't have to worry about recoding my changes every time the file gets regenerated.

All that's left is to add a mechanism for individual columns to find their applicable errors.

public void AddError(string propertyName, string error)
{
    if (!errors.ContainsKey(propertyName))
        errors[propertyName] = new List<string>();

    if (!errors[propertyName].Contains(error))
        errors[propertyName].Add(error);
}

 
public void RemoveError(string propertyName, string error)
{
    if (errors.ContainsKey(propertyName) &&
        errors[propertyName].Contains(error))
    {
        errors[propertyName].Remove(error);
        if (errors[propertyName].Count == 0) 
            errors.Remove(propertyName);
    }
}

public string this[string columnName]
{
    get
    {
        return (!errors.ContainsKey(columnName) ? null :
            String.Join(Environment.NewLine, errors[columnName]));
    }
}

This last method gets called when a binded-to control requests errors for a column name.

In our next post we will be using the MortDB DataContext in the code.

Download the Code Here

Basic Navigation and XAML

In the last post we looked at the structure of the database. Now we get to dive into WPF application creation.

My original Mortgage Calculator suffered from a horrible GUI. Not only did it use modal windows when it wasn't necessary, the whole layout is incomprehensible.










Notice that the top 3/4 is wasted on user input, buttons and a text box that when clicked gave a summary of the information.

WPF has addressed these issues by providing layout components such as DockPanel, StackPanel, Expander and ScrollViewer to name some. More on that later.

Basic Page Setup

As noted before, I wanted to have 1 window with multiple states. WPF lets us accomplish this by using the NavigationWindow class. NavigationWindow allows an application to "navigate" between any .NET Framework object and HTML page. It's mostly used with the Page class, which is what we will be using it for.

Lets create our first Navigation Window.

<NavigationWindow x:Class="MortCalc.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="Mortgage Calculator" Height="350" Width="500" WindowState = "Maximized" Source="MortgageHome.xaml">

</NavigationWindow>

That was simple. I should change my xml namespaces : ) We have specified the title, default size, how the window looks when we open it (WindowState), and the first Page to show in our Navigation Window (Source).

Lets take a look at the code behind this xaml file.

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.Navigation;
using System.Windows.Shapes;

namespace MortCalc
{
    /// <summary>
    /// Interaction logic for MainWindow.xaml
    /// </summary>
    public partial class MainWindow : NavigationWindow
    {
        public MainWindow()
        {
            InitializeComponent();
        }
    }
}

Again relatively straight forward.

Home Page

The first page should list all of the mortgages currently in the database and allow the user add new Mortgages.

Lets take a look at it.



















Notice that we can select the Mortgage Based upon the Name. In my previous version I listed all the relevant details if the Name did not provide enough information. This would make a decent future improvement.

Also the user can create a new Mortgage.

The xaml is again relatively straight forward.

<Page x:Class="MortCalc.MortgageHome"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="Mortgage - Home" Height="auto" Width="auto" Loaded="Page_Loaded" Background="Beige">
    <DockPanel LastChildFill="True" Margin="10,0,10,10">
        
        <Label DockPanel.Dock="Top" Style="{StaticResource headerTextStyle}" >
            View Mortgages:
        </Label>
        
        <Grid DockPanel.Dock="Bottom" >
            <Grid.RowDefinitions>
                <RowDefinition/>
            </Grid.RowDefinitions>
            <Grid.ColumnDefinitions>
                <ColumnDefinition />
                <ColumnDefinition Width="Auto"/>
            </Grid.ColumnDefinitions>
            <Button Grid.Row="0" Grid.Column="0" HorizontalAlignment="Right" Click="New_Button_Click" Style="{StaticResource buttonStyle}">
                New
            </Button>
            <Button Grid.Row="0" Grid.Column="1" HorizontalAlignment="Right" Click="Amortize_Button_Click" Style="{StaticResource buttonStyle}">
                Amortize
            </Button>
        </Grid>

        <ListBox Name="mortgageListBox"  DisplayMemberPath="Name" FontSize="18" />
        
    </DockPanel>
</Page>

The whole page is contained inside a DockPanel. DockPanel allows for children UI elements to be position relative to one another. LastChildFill="True" specifies that the last item in the list of children expands to fill any left over space in the Panel. In this case our ListBox with the Names of the Mortgages is the "Fill."

Each child element can specify what type of positioning inside of the DockPanel it is using with DockPanel.Dock. Our "View Mortgages:" Label uses DockPanel.Dock="Top" to position it at the top of the page.

We have put the buttons inside of a grid to ensure proper spacing. The Grid must contain Row and Column Definition sections. We have set the 2nd column to Width="Auto" which ensures auto sizing of the column.

Children inside of the Grid need to specify their Row and Column location. You can see this in the Grid.Row="" and Grid.Column="" values.

There are Several Style="{...}" attributes in this file. In particular these point to values specified somewhere else. They could be listed in the Page.Resources section or in this case in our App.xaml file.
<Style x:Key="headerTextStyle">
    <Setter Property="Label.VerticalAlignment" Value="Center"></Setter>
    <Setter Property="Label.FontFamily" Value="Trebuchet MS"></Setter>
    <Setter Property="Label.FontWeight" Value="Bold"></Setter>
    <Setter Property="Label.FontSize" Value="18"></Setter>
    <Setter Property="Label.Foreground"Value="#000000"></Setter>
</Style>

<!-- Button style -->
<Style x:Key="buttonStyle" TargetType="{x:Type Button}">
    <Setter Property="Width" Value="125" />
    <Setter Property="Height" Value="25" />
    <Setter Property="Margin" Value="0,10,0,0" />
    <Setter Property="HorizontalAlignment" Value="Right" />
</Style>
When MortgageHome.xaml's button specified a Style="{StaticResource buttonStyle}" it was specifically referencing the App.xmal's buttonStyle Style element.

Click="New_Button_Click" specifies a function that gets called in the code behind file when the click event gets triggered.

Lastly, DisplayMemberPath="Name" is a form of binding.

We will be diving into the click event and binding more in future posts. The next post when we see how CRUD gets implemented.


Download the Code Here

Mortgage Calculator Database

SQL Server Compact

In the last post I gave a basic overview of my reasons and goals for Mortgage Calculator.

I love Microsoft. In particular I love how much time and effort they spend making the developer's life easier.

When I do anything outside my current job I default to .NET and C#.

While there are many capable database technologies out there, I was most certainly going to settle on something Redmond has implemented.

For Mortgage Calculator, I wanted something simple, light and capable for the database back end.

Aside from SQL Server, MS has Access.

SQL Server itself comes in a variety different flavors. The 2 most applicable being:
  • SQL Server Express
  • SQL Server Compact

MS Access is out, because, well it's Access. Also, I was keen on using LINQ to SQL.

SQL Server Express is more then capable. However, in order to use Express in your application you need to embed the SQL Server Express install into your install. This might be acceptable but I would just prefer to avoid it.

SQL Server Compact is file based. The beauty of which is that installing it to a user's machine involves adding the .sdf file and a few dlls for communicating with the file.

Database Table(s)

Because the concept of Mortgage Calculator is rather simple the information that needs to be stored is also simple.

Remember from the first post we want to keep track of the following values:
  • Principal
  • Interest
  • Extra Payments
  • Balance
  • Home Value
  • Tax
  • Insurance
  • Association Dues
  • Maintenance
  • Total Monthly Cost
  • Equity
  • Loan To Value
  • Rental Income
  • Cash Flow
  • Tax Appreciation
  • Insurance Appreciation
  • Association Dues Appreciation
  • Maintenance Appreciation
  • Rent Appreciation
  • Home Value Appreciation

Again, due to the simplicity of the app it is assumed there is only one user per install (potential future improvement). All we are left with is individual Mortgages that need to be amortized. Therefore we have 1 table.

Lets create it.


Numeric to Decimal

Because float and double values are not exact (Greg Dolley has a good write up on the Double vs Decimal issue) and it's accepted practice, we are going to be typing our money and interest rates in decimal in C#.

Decimal's counter part in SQL Server Compact is numeric.

Notice we have 2 different numeric types:
  1. numeric(18,2)
  2. numeric(18,5)
The first number is Precision and determines the number of digits in the value. The second is Scale and determines the number digits to the right of the decimal place.

So our values become something like the following:

1,234,567,890,123,456.78
1,234,567,890,123.45678

Because those values can become large and using decimals can be 20x more slow then doubles or floats we have to be careful to limit the input and processing on the machine.

In a future release I will have to update the interest rates to have more scale.

Currently, rounding is 5 decimal places which means rounding can result in:
  • $100,000,000 x 0.000009 = $900, $900 / 12 = $75
This means someone lost $75 a month. We want to aim for less than $0.01 a month.
  • $100,000,000 x 0.0000000009 = $0.09, $0.09 / 12 = $0.0075
Now someone is only losing $0.09 a year. 18 places means the interest rate can be 1,234,567.0000000009%. We could cap the interest rates at 1000% and feel comfortable that anything over that is for theoretical purposes and outside the scope of this project.

Show - Expand

There are several "Show" and "Expand" bit/boolean values in the table. These deal with preserving GUI state for different Mortgages and will be covered in a future post.

Null or Not Null

The only columns that are not allowed to be null are the Key, Name and the values necessary to do a basic Amortization.
  • Key
  • Name
  • Principal
  • Interest Rate
  • Term
For everything else we would prefer not to enforce updating information if we don't have to.

In the next post we will be exploring more of the xmal side of our Navigation and Home Page.


Download the Code Here

Mortgage Calculator App

WPF

In order to get a better understanding of Windows Presentation Foundation (WPF) I've decided to dive right in.

A while back I had created a Mortgage Calculator in C# .NET 1.2 as a Windows Form Application:



















However, the GUI implementation left something to be desired. I wanted to avoid using modal forms. Instead the UI needed to be isolated to one window. While a trivial task, adding 2 panels to a form and switching the visible property seemed like a hack and annoying to maintain. Other suggestions seemed to suffer from the same basic problems.

Enter WPF. WPF uses DirectX which pipes all the UI processing to the GPU. This saves the CPU from wasting calculations. The following post on stackoverflow.com has a fairly succinct break down of it.

Instead of generating the GUI with pure code as Windows Form Application does, WPF uses Extensible Application Markup Language (XAML). XAML is an XML based user interface markup language. It's values define UI elements, data binding, events and more.

Using WPF, implementing a form with multiple GUI states doesn't feel as clumsy. Also, databinding takes away much of the coding I used to encounter with loading, validating and updating values in the database.

Mortgage Calculator

The Mortgage Calculator is intended to give your average everyday landlord/amateur investor a rough estimate of what his properties vital stats will be month by month in the amortization schedule.

A problem with most Mortgage Calculators, especially at Real Estate or Mortgage websites, is their lack of data. In particular, leaving out Tax and Insurance from the monthly payment might give someone unrealistic expectations of their out of pocket costs.




Mortgagecalculator.org includes tax but leaves out insurance and Association dues.

As an example lets pull up a listing from http://mihome.mobi/:






















Plugging this information into MortgageCalculator.org we get:



















$24,375.00 doesn't tell us much. Did the property tax increase over the 30 year amortization or is this a fixed dollar amount every year?

$24,375 breaks down to $812.50 a year.

Again we have no idea about Insurance or Association Dues.

When we scroll down in the listing we find that the tax was underestimated.











Perhaps we had the wrong percentage? Yes, but home values used to calculate property tax themselves are figured out by a city tax assessors who's valuations can differ from the current market value. Simply stated the only tax rate that matters is the current dollar amount listed, which in this case is $582.50 higher.

Principal and Interest Payment: $348.93
Tax: $1,395 / 12 = $116.25
Insurance: $500 / 12 = $41.67
Association Dues: $246

Total Payment: $752.85

Almost double what MortgageCalculator.org showed!

What about the changes in tax, insurance and other costs? If the total payment now is $752.85 it will most certainly become more expensive in the future.

I designed Mortgage Calculator to address 3 main areas where details were lacking:
  1. Total cost of owning and maintaining the house.
  2. Future appreciation of all costs.
  3. Rental stats.
In the amortization schedule I would want to track the following:
  • Principal
  • Interest
  • Extra Payments
  • Balance
  • Home Value
  • Tax
  • Insurance
  • Association Dues
  • Maintenance
  • Total Monthly Cost
  • Equity
  • Loan To Value
  • Rental Income
  • Cash Flow
On top of this I would want to assign appreciation rates to the following values:
  • Tax
  • Insurance
  • Association Dues
  • Maintenance
  • Rent
  • Home Value
In our next post we will be dealing with creation of the Database.


Download the Code Here