In my F# Avalonia FuncUI desktop app, I wanted a callback when the user presses the mouse 'Back' button in my FuncUI component. I eventually got it working using reflection, as below. I was wondering if I am missing a cleaner or more obvious way of doing this? Should I be raising this as an issue on the FuncUI github repository?
open Avalonia.FuncUI
let getProtectedPropertyValue (name: string) (obj: obj) =
let propertyInfo =
obj.GetType().GetProperty(
name, BindingFlags.Instance |||
BindingFlags.NonPublic ||| BindingFlags.Public)
if propertyInfo <> null && propertyInfo.CanRead then
propertyInfo.GetValue(obj)
else
failwith $"Property '{name}' not gettable"
ctx.attrs [
Component.onPointerPressed (fun event ->
let properties =
getProtectedPropertyValue "Properties" event :?>
PointerPointProperties
if properties.IsXButton1Pressed then
DoSomething()
)
]
Thanks to JL0PD's comment, I discovered an Avalonia GitHub Issue, which has the answer to how to directly access the property I was after, without resorting to reflection. Here is the corrected code in F# for Avalonia FuncUI:
open Avalonia.FuncUI
Component(fun ctx ->
ctx.attrs [
Component.onPointerPressed (fun event ->
let properties = event.GetCurrentPoint(ctx.control).Properties
if properties.IsXButton1Pressed then
event.Handled <- true // prevent second callback on pointer button release
DoSomething()
)
]
I was later caught out by the event happening twice, which I suspect is because it is called for both press and release of the button.