Friday, June 05, 2009

Exploring WPF Toolkit's DataGrid with F#

I recently received an invitation from Martin Szummer to take a look at the DataGrid control that's part of the WPF Toolkit. That got me curious and I quickly mocked up some code to start exploring the DataGrid with some F# script. Here's is the F# script that I'm using to explore this control:

#I @"C:\Program Files\Reference Assemblies\Microsoft\Framework\v3.0"
#r @"WindowsBase.dll"
#r @"PresentationCore.dll"
#r @"PresentationFramework.dll"
#r "C:\Program Files\WPF Toolkit\v3.5.40320.1\WPFToolkit.dll"

open Microsoft.Windows.Controls
open System
open System.Data.Common
open System.Data.Sql
open System.Data.SqlClient
open System.Windows
open System.Windows.Controls

let connString = @"Data Source=.\SQLEXPRESS;Initial Catalog=AdventureWorks;Integrated Security=True;"

let conn = new SqlConnection(connString)

type Person =
{FirstName:string; LastName:string; Email:string; PhoneNumber:string}

let query () =
seq { use conn = new SqlConnection(connString)
do conn.Open()
use comm = new SqlCommand("SELECT top 100 * FROM Person.Contact",conn)
use reader = comm.ExecuteReader()
while reader.Read() do
yield ({FirstName = reader.GetString 3;
LastName = reader.GetString 5;
Email = reader.GetString 7;
PhoneNumber = reader.GetString 9}) }

let win = new Window(Title="Test DataGrid")

let datagrid = DataGrid()
datagrid.HeadersVisibility <- DataGridHeadersVisibility.Column
datagrid.ItemsSource <- query() |> Seq.to_array

win.Content <- new ScrollViewer(Content=datagrid)


Coden Enteprises said...

I have a question on the while loop. I am trying currently to do something similiar with out using a while. Can you code an example using recursion if possible.

John Liao said...

There's probably many way to get rid of the while loop, but I'm not sure if that's good idea or not. In the sections with code that is not purely functional, it might make more sense to have code constructs that looks imperative. But here's a sample code that does the same thing without the while statement and uses recursion:

let rec retrieve (reader:SqlDataReader) =
  if reader.Read() then
    {FirstName = reader.GetString 3;
    LastName = reader.GetString 5;
    Email = reader.GetString 7;
    PhoneNumber = reader.GetString 9} :: (retrieve reader)

let query2 () =
  use conn = new SqlConnection(connString)
  do conn.Open()
  use comm = new SqlCommand("SELECT top 50 * FROM Person.Contact",conn)
  use reader = comm.ExecuteReader()
  retrieve reader