Monday, June 28, 2010

WPF MVVM Multi-Project Template: A Polyglot Approach

In my last post, I provided a WPF MVVM multi-project template comprised entirely of F# projects.  While that approach is exciting, I found that having the Views in an F# project caused more pain than gain.  As an advocate for using the right tool for the job, I have created a new WPF MVVM multi-project template composed of an C# View project, an F# ViewModel project, and an F# Model project.  Additionally, this version includes an F# Repository project and an F# project called FSharpIoC that provides inversion of control functionality (this can easily be replaced with the IoC contrainer of your choice).

The F# code did not change significantly between this version and the last; however, the ExpenseItHomeViewModel.fs has been cleaned up due to refactoring and the introduction of the ExpenseReportRepository.

Here's the code:
namespace FSharpWpfMvvmTemplate.ViewModel

open System
open System.Windows
open System.Windows.Data
open System.Windows.Input
open System.ComponentModel
open System.Collections.ObjectModel
open FSharpWpfMvvmTemplate.Model
open FSharpWpfMvvmTemplate.Repository

type ExpenseItHomeViewModel(expenseReportRepository : ExpenseReportRepository)  =  
    inherit ViewModelBase()
    let mutable selectedExpenseReport = 
        {Name=""; Department=""; ExpenseLineItems = []}
    new () = ExpenseItHomeViewModel(
    member x.ExpenseReports = 
        new ObservableCollection<ExpenseReport>(
    member x.ApproveExpenseReportCommand = 
        new RelayCommand ((fun canExecute -> true), (fun action -> x.ApproveExpenseReport)) 
    member x.SelectedExpenseReport 
        with get () = selectedExpenseReport
        and set value = 
            selectedExpenseReport <- value
            x.OnPropertyChanged "SelectedExpenseReport"
    member x.ApproveExpenseReport = 
        MessageBox.Show(sprintf "Expense report approved for %s" x.SelectedExpenseReport.Name) |> ignore

You can find the template installer here and the full source at

No comments:

Post a Comment