F# WPF MouseMove params

474 views Asked by At
canvas.MouseMove.Add(move canvas update)

MouseMove.Add( p1 p2 p3)

Usually I see this use and documentation, two params -- (object sender, MouseEventArgs e) -- which I take to be move and canvas in this example code, taken from F#.NET Journal's Computational geometry: quick hull.

Is update some delagate? or routing bubble info to MouseMove.Add?

I'm just not gettng it. Any help welcome. Thanks. Art

2

There are 2 answers

1
Tomas Petricek On BEST ANSWER

The answer from kvb gives all the theory, so I thought I could also add a code sample. I don't know the source of the snippet, so I'll make some guesses based on the names - hopefully it will be useful even if it may not be completely same as the original sample.

As kvb says, the code move canvas update is actually a function call that returns a function, which is then added as a handler to the MouseMove event.

This means that move could be declared as follows:

let move (canvas:Canvas) (update:unit -> unit) (me:MouseEventArgs) =
  // This function gets called when the mouse moves
  // - values me.X and me.Y give the current mouse location
  // - we can access 'canvas' that was declared when registering handler
  // - we can call 'update' to do some more work...
  // Pseudo-example:
  canvas.Children.[0].Width <- me.X
  update()

When registering the event handler, the code move canvas update specifies the first two arguments of the move function, so that the handler can access canvas value that was probably declared in the place where the handler is registered (without the use of mutable variables!)

let canvas = new Canvas() // Create canvas
let update () = ... // some function that performs update

// Register handler and give it canvas and update as first two arguments
canvas.MouseMove.Add(move canvas update) 

This should also explain why the event handler does not need to take sender:object as the first argument - you can pass the canvas (which is the sender) as a first argument using partial function application in a statically typed way (so you don't have to cast object to Canvas).

2
kvb On

Unless you've got a typo, move canvas update is the application of the function move to the values canvas and update, none of which you are showing; this is not a set of 3 separate arguments being passed.

In general, in F# events work slightly differently than they do in other .NET languages. When you use the Add method, you pass a function which takes a single EventArgs subclass, not the sender and the event args. If you want to access the sender from within the handler, then use AddHandler instead; usually this isn't necessary because the sender is just the object on which you're adding the handler, so you don't need to get a separate reference to it from within the handler.