Xamarin.forms Xamarin表单:点击事件Args派生类型
我有一些这样的代码可以很好地工作:Xamarin.forms Xamarin表单:点击事件Args派生类型,xamarin.forms,f#,Xamarin.forms,F#,我有一些这样的代码可以很好地工作: type App() = inherit Application() let stack = StackLayout(VerticalOptions = LayoutOptions.Center) let label = Label(XAlign = TextAlignment.Center, Text = "Welcome to F# Xamarin.Forms!") do let tapRecognize
type App() =
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 (sender:Object) (args:EventArgs) =
label.Text <- "Tapped at " + DateTime.Now.ToString()
()
let tapEventHandler = new EventHandler(handleTapEvent)
tapRecognizer.Tapped.AddHandler(tapEventHandler)
label.GestureRecognizers.Add(tapRecognizer)
type App()=
继承应用程序()
让堆栈=堆栈布局(垂直选项=布局选项.Center)
让label=label(XAlign=TextAlignment.Center,Text=“欢迎使用F#Xamarin.Forms!”)
做
让tapRecognizer=新建TapGestureRecognizer()
let handleTapEvent(发送方:对象)(args:EventArgs)=
label.TextF#不会像C#那样自动插入下拉列表(这是一件好事,不是一个bug)。不能传递预期为祖先类型的子类型
为了调用AddHandler
,您需要使用downcast操作符:>
手动插入downcast,如下所示:
type TapEventArgs(someId:int) =
inherit EventArgs()
member this.SomeId = someId
let handleTapEvent (sender:Object) (args:TapEventArgs) =
label.Text <- args.SomeId.ToString() + " tapped"
()
let tapEventHandler = new EventHandler<TapEventArgs>(handleTapEvent)
tapRecognizer.Tapped.AddHandler(tapEventHandler :> EventHandler<EventArgs>)
这里的问题是类型不同,这就是F#告诉你的。tap识别器.Tapped
的类型为EventHandler
,因此当调用它时,它将为EventHandler
类型,即不是EventHandler
,这是一种不同的类型。无法更改这一点,而且由于类是密封的,因此不可能对TapGestureRecognitor
进行子类化
此外,您发布的代码将很难编译,因为它具有循环引用,这是F#所阻止的TapEventArgs
需要标签
,该标签在应用程序中定义<代码>应用程序
取决于TapEventArgs
。无法从TapEventArgs
更新UI,而是需要传入函数,或者暴露状态
有一种使用命令
模式的解决方案,它允许将一些信息传递给回调,并避免循环依赖TapGestureRecognitor
有一个属性CommandParameter
,其中可以设置值(obj类型)。可以通过可接收该值的命令
属性提供回调。以下是完整的示例:
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
开放系统
键入App(),如下所示=
继承应用程序()
让堆栈=堆栈布局(垂直选项=布局选项.Center)
让label=label(XAlign=TextAlignment.Center,Text=“欢迎使用F#Xamarin.Forms!”)
做
让tapRecognizer=新建TapGestureRecognizer()
让handleTapEvent(x:obj)=
将x与
| :? int as someId->label.Text label.Text在AddHandler方法中添加向下转换不起作用。tapRecognizer.Tapped.AddHandler(tapEventHandler:>EventHandler)抛出此表达式应具有类型“EventHandler”,但此处具有类型“EventHandler”tapRecognizer.Tapped的类型是什么?
tapRecognizer.Tapped.AddHandler(tapEventHandler :> _)
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)