F# and WPF

Dear functional programmers,

this is a short trip to desktop development in .Net.

mvvm

If you like F#, you will design some models with record types and maybe you retrieve their items with type providers


// business model
type Invoice = { CptyName: string; CptyNum: int; InvoiceNr: string; amount : decimal; curr: string; buysell: ActivePassive}
// array extraction from Excel with type provider
let ActiveInvoice =
ActiveInvoiceExcel.Data
|> Seq.map ( fun line -> { InvoiceNr = line.Numero documento; ... })
|> Seq.toArray

view raw

model.fs

hosted with ❤ by GitHub

Now you bind the array to a DataGrid and you can show a nice UI.


<DataGrid Grid.Column="2" ItemsSource="{Binding SelPayment.eur_invoices}" IsReadOnly="True"
HorizontalAlignment="Stretch" VerticalAlignment="Stretch" Margin="10,10,10,10" >

view raw

view.xaml

hosted with ❤ by GitHub

Problem

What if you want to update a status message from the app logic to some items of the UI?

Do you have to refactor all those records into plain old objects (= classes)?

Compositional trick

Well, that’s not need! You simply leverage the compositional property of the binding path in .Net implementation of the MVVM pattern.

So you just add a new ui member to the F# record type


type Back2UI() =
inherit SimpleViewModelBase()
let mutable _msg = ""
member this.msg
with get() = _msg
and set value =
_msg <- value
this.OnPropertyChanged(<@ this.msg @>)
type ActivePassive = Active | Passive
type Invoice = { CptyName: string; CptyNum: int; InvoiceNr: string; amount : decimal; curr: string; buysell: ActivePassive; ui: Back2UI}

view raw

model_v2.fs

hosted with ❤ by GitHub

and you define the binding in a grid column


<DataGrid Grid.Column="2" ItemsSource="{Binding SelPayment.eur_invoices}" IsReadOnly="True" AutoGenerateColumns="False"
HorizontalAlignment="Stretch" VerticalAlignment="Stretch" Margin="10,10,10,10" >
<DataGrid.Columns>
<DataGridTextColumn Header="Buy/Sell" Binding="{Binding buysell}" />
<DataGridTextColumn Header="Cpty Name" Binding="{Binding CptyName}" />
<DataGridTextColumn Header="Invoice Nr" Binding="{Binding InvoiceNr}" />
<DataGridTextColumn Header="Amount" Binding="{Binding amount, StringFormat=N}" />
<DataGridTextColumn Header="Curr" Binding="{Binding curr}" />
<DataGridTextColumn Header="Msg" Binding="{Binding ui.msg}" />
</DataGrid.Columns>
</DataGrid>

view raw

view_v2.xaml

hosted with ❤ by GitHub

Happy coding, cheers!

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s