How do I properly call a F# function from WPF?

28 views
Skip to first unread message

Shane Delmore

unread,
Jul 20, 2012, 7:26:05 PM7/20/12
to fsh...@googlegroups.com
I have been digging into the WPFSample project today and an unsure of the visibility rules of how to make calls from the UI to the F# code.

Using the very lightly modified xaml included (I just added a datagrid) below:
<Window xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="MainWindow" Height="346" Width="654" Name="MainWindow" >
    <Grid Name="MainGrid">
        <StackPanel Name="StackPanel1">
            <Button Name="Button1">First Button</Button>
            <Button Name="Button2">Second Button</Button>
            <DataGrid x:Name="dataGrid1" HorizontalAlignment="Left" Width="570" Height="217"/>
        </StackPanel>
    </Grid>
</Window>

And just adding linq to the sample Program.fs I tried to enable hooking up a datasource based on a button press.

open System
open System.Windows
open System.Windows.Controls
open FSharpx
open System.Data
open System.Data.Linq
open Microsoft.FSharp.Data.TypeProviders

type MainWindow = XAML<"Window.xaml">

type dbSchema = SqlDataConnection<"Data Source=clntsqlvs01;Initial Catalog=AdminDB;Integrated Security=SSPI;">

let db = dbSchema.GetDataContext()

let query1 = query { for customerSession in db.CustomerSessions do
                     select customerSession }

let hookupQuery = window.DataGrid1.ItemsSource <- query1

let loadWindow() =
    let window = MainWindow()
    window.DataGrid1.ItemsSource <- query1
    window.Button1.Click.Add(fun _ ->
        MessageBox.Show("Hello world!")
        |> ignore)
    window.Button2.Click.Add(fun _ ->
        window.DataGrid1.ItemsSource <- query1
        |> ignore)
    window.MainWindow

[<STAThread>]
(new Application()).Run(loadWindow())
|> ignore


I have commented out the section that does not work but I am stuck in this area:
1.  If I set the datasource in loadWindow it works.
2.  If I try to add the event to connect the datagrid to button2 it complains that The type unit is not compatible with type Collections.IEnumerable   
3.  If I define a function to hook them up with no output as
    let hookupQuery = window.DataGrid1.ItemsSource <- query1
    it doesn't appear to be able to see window.
4.  If I define the function within the loadwindow function as
let loadWindow() =
    let window = MainWindow()
    let hookupQuery = window.DataGrid1.ItemsSource <- query1
    window.Button1.Click.Add(fun _ ->
        MessageBox.Show("Hello world!")
        |> ignore)
    window.Button2.Click.Add(fun _ ->
        hookupQuery
        |> ignore)
    window.MainWindow
 then it runs automatically.  Am I actually executing the code behind hookupQuery, not just defining it to be called later?

-Shane

Johann Deneux

unread,
Jul 21, 2012, 12:10:46 PM7/21/12
to fsh...@googlegroups.com
let hookupQuery = ...
should be
let hookupQuery() = ...

Otherwise, it's not a function but a value (of type unit, in this case).
Reply all
Reply to author
Forward
0 new messages