Проблема здесь в том, что типы разные, и это то, что F # говорит вам.Тип tapRecognizer.Tapped
имеет EventHandler
, поэтому, когда он вызывается, он будет иметь тип EventHandler
, т.е. не EventHandler<TapEventArgs>
, который является другим типом.Изменить это невозможно, и подкласс TapGestureRecognizer
также невозможен, так как класс запечатан.
Кроме того, код, который вы разместили, будет трудно скомпилировать, поскольку он содержит циклические ссылки, которые F # предотвращает.TapEventArgs
требует label
, что определено в App
.App
зависит от TapEventArgs
.Было бы невозможно обновить пользовательский интерфейс с TapEventArgs
, вместо этого необходимо было бы передать функцию или выставить состояние.
Существует решение, использующее шаблон Command
, который позволяет некоторой информациипередаваться в обратный вызов и избегает циклических зависимостей.TapGestureRecognizer
имеет свойство CommandParameter
, где может быть установлено значение (типа obj).Обратный вызов может быть предоставлен через свойство Command
, которое может получить это значение.Вот полный пример:
open Xamarin.Forms
open System
type App() as this =
inherit Application()
let stack = StackLayout(VerticalOptions = LayoutOptions.Center)
let label = Label(XAlign = TextAlignment.Center, Text = "Welcome to F# Xamarin.Forms!")
do
let tapRecognizer = new TapGestureRecognizer()
let handleTapEvent (x:obj) =
match x with
| :? int as someId -> label.Text <- someId.ToString() + " tapped"
| _ -> label.Text <- "Tapped at " + DateTime.Now.ToString()
tapRecognizer.Command <- new Command(Action<obj>(fun x -> handleTapEvent x))
label.GestureRecognizers.Add(tapRecognizer)
stack.Children.Add label
tapRecognizer.CommandParameter <- 42 // The value to be passed to the Command's callback
this.MainPage <- ContentPage(Content = stack)
Обратите внимание, что приведение типов должно использоваться из-за способа определения типов в Xamarin.Forms (для свойства используется obj
).