GMc
GMc

Reputation: 53

Avalonia FuncUI PointerPressedEventArgs, how to access protected member without using reflection?

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()
  )
]

Upvotes: 0

Views: 139

Answers (1)

GMc
GMc

Reputation: 53

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.

Upvotes: 0

Related Questions