views:

101

answers:

2

Does anyone know how to add an F# event handler to a control in the xaml file?

+1  A: 

Essentially you need to load a xaml file and find a control by name:

let w = Application.LoadComponent(new  System.Uri(
          "/twitterstream;component/Window.xaml", System.UriKind.Relative
        )) :?> Window
let b = w.FindName("buttonToggle") :?> Button

and then you can simple add a handler an event:

b.Click.Add(fun _ -> ...)

You can get fancy and use first-class event combinators - here is a great step-by-step introduction:

http://blogs.msdn.com/b/timng/archive/2010/05/06/f-wpf-events.aspx

Mitya
+1  A: 

I just gave a talk about reactive programming in F# (in London) that used Silverlight to implement most of the examples. The talk has been recorded and the samples are available for download as well, so this may be a useful resource:

To answer your specific question, I don't think that you can use the usual style of specifying event handler in the XAML file (this may work in F# Silverlight Application, but you would have to use member instead of let function).

However, the best way (I can think of) for writing Silverlight components is to have just an F# Silverlight Library and use that from a C# Silverlight application. In that case, you need to write the event handler binding in code. A simplified example (from one of the samples from the talk) would look like this:

open System.Windows.Controls

// Dynamic invoke operator that makes accessing XAML elements easy 
// (easier than using 'FindName' explicitly in the code
let (?) (this : Control) (prop : string) : 'T = // '
  this.FindName(prop) :?> 'T // '

type MyControl() as this =
  inherit UserControl()
  do 
    let path = "/MyProject;component/MyControl.xaml"
    let uri = new System.Uri(path, UriKind.Relative)
    Application.LoadComponent(this, uri)

    // Get Button named 'TestButton' from the XAML file
    let btn : Button = this?TestButton
    // Add event handler to the button
    btn.Add(fun _ -> btn.Text <- "Clicked!")
Tomas Petricek