Search code examples
f#avaloniaui

How to get click position from event in Avalonia.FuncUI


I'm trying to figure out how I can access the pointer position of a mouse click from the event click. I've came up with something like

[...]
    type State = { coords: Point list }

    type Msg = Click of Point

    let update (msg: Msg) (state: State) : State =
        match msg with
        | Click p -> { state with coords = p::state.coords }


    let view (state: State) dispatch =
        Canvas.create [
             Canvas.onPointerPressed (fun event -> event.GetPosition ??? |> Click |> dispatch)
         ]
[...]

But that would require a handle to the control in place of ???, to which i have no access. Is there another way? Or a way the get a handle to the control?

Probably I'm missing something.


Solution

  • You can use the Source Property on the PointerPressedEventArgs (or any other RoutedEventArgs) to obtain a reference to the firing Control.

    let view (state: State) dispatch =
        Canvas.create [
             Canvas.background "white"
             Canvas.onPointerPressed (fun event -> event.GetPosition (event.Source :?> IVisual) |> Click |> dispatch)
             Canvas.children [
                 for point in state.coords do
                     yield Ellipse.create [
                         Ellipse.width 5.0
                         Ellipse.height 5.0
    
                         Ellipse.fill "red"
                         Ellipse.top (point.Y - 2.5)
                         Ellipse.left (point.X - 2.5)
                     ]
             ]
        ]
    

    Also note that you need to set the Background Property of a Canvas or you won't get PointerPressed events.

    You also need to open the Avalonia.Controls.Shapes namespace if you want to use the Example above (because of Ellipse).