Events 仅在其他事件期间侦听事件
只有在按下鼠标按钮(MouseDown事件)后,我才能收听MouseMove事件Events 仅在其他事件期间侦听事件,events,f#,Events,F#,只有在按下鼠标按钮(MouseDown事件)后,我才能收听MouseMove事件 我基本上是在F#forms应用程序中寻找单击->拖动->释放功能在鼠标下键事件中为移动和向上添加事件侦听器,在向上键事件中删除它。这确实意味着处理程序方法需要是一个方法(或者您需要保留所使用的委托)才能传递给事件的remove方法 (如果这是针对C#,我会向您指出Rx的反应式扩展,因为这可能是一个定义性的示例,但我不确定Rx与F#的配合效果如何。)在鼠标按下事件中为“移动”和“向上”附加事件侦听器,在“向上”事件中
我基本上是在F#forms应用程序中寻找单击->拖动->释放功能在鼠标下键事件中为移动和向上添加事件侦听器,在向上键事件中删除它。这确实意味着处理程序方法需要是一个方法(或者您需要保留所使用的委托)才能传递给事件的remove方法
(如果这是针对C#,我会向您指出Rx的反应式扩展,因为这可能是一个定义性的示例,但我不确定Rx与F#的配合效果如何。)在鼠标按下事件中为“移动”和“向上”附加事件侦听器,在“向上”事件中删除它。这确实意味着处理程序方法需要是一个方法(或者您需要保留所使用的委托)才能传递给事件的remove方法
(如果这是针对C#的,我会向您指出Rx无功扩展,因为这可能是定义性的示例,但我不确定Rx与F#的配合效果如何。)您也可以使用类似的方法:
let setupDrag(target, fn) =
let isDown = ref false
target.MouseDown |> Event.add(fun _ -> isDown := true)
target.MouseMove |> Event.filter(fun _ -> !isDown) |> Event.add(fn)
target.MouseUp |> Event.add(fun( _ -> isDown := false)
在实际的实现中,当转换开始、停止以及所有这些事情时,您可能希望实际执行其他事情。例如,您可能希望捕获目标上的指针。您也可以使用类似以下内容:
let setupDrag(target, fn) =
let isDown = ref false
target.MouseDown |> Event.add(fun _ -> isDown := true)
target.MouseMove |> Event.filter(fun _ -> !isDown) |> Event.add(fn)
target.MouseUp |> Event.add(fun( _ -> isDown := false)
在实际的实现中,当转换开始、停止以及所有这些事情时,您可能希望实际执行其他事情。例如,您可能希望捕获目标上的指针。使用F#async工作流机制可以很好地捕获此行为。我写了一篇关于这方面的文章(实现了拖放式的功能),在这里您可以找到详细信息-请参阅 示例应用程序实现绘图,您可以在其中按下一个按钮,然后移动鼠标(定义一个矩形),然后最终释放按钮:
let rec drawingLoop(clr, from) = async {
// Wait for the first MouseMove occurrence
let! move = Async.AwaitObservable(form.MouseMove)
if (move.Button &&& MouseButtons.Left) = MouseButtons.Left then
// Refresh the window & continue looping
drawRectangle(clr, from, (move.X, move.Y))
return! drawingLoop(clr, from)
else
// Return the end position of rectangle
return (move.X, move.Y) }
let waitingLoop() = async {
while true do
let! down = Async.AwaitObservable(form.MouseDown)
let downPos = (down.X, down.Y)
if (down.Button &&& MouseButtons.Left) = MouseButtons.Left then
let! upPos = drawingLoop(Color.IndianRed, downPos)
do printfn "Drawn rectangle (%A, %A)" downPos upPos }
这里的好处是,您可以很好地表达逻辑-等待MouseDown
(在waitingLoop
内部),然后调用drawingLoop
函数,等待MouseMove
,直到松开按钮(然后将控件传输回waitingLoop
,它开始等待另一个鼠标按下事件)
类似代码的另一个版本在中
完整的源代码是其中的一部分。使用F#async workflows机制可以很好地捕获这种行为。我写了一篇关于这一点的文章(完全实现了拖放式功能),您可以在其中找到详细信息-请参阅 示例应用程序实现绘图,您可以在其中按下一个按钮,然后移动鼠标(定义一个矩形),然后最终释放按钮:
let rec drawingLoop(clr, from) = async {
// Wait for the first MouseMove occurrence
let! move = Async.AwaitObservable(form.MouseMove)
if (move.Button &&& MouseButtons.Left) = MouseButtons.Left then
// Refresh the window & continue looping
drawRectangle(clr, from, (move.X, move.Y))
return! drawingLoop(clr, from)
else
// Return the end position of rectangle
return (move.X, move.Y) }
let waitingLoop() = async {
while true do
let! down = Async.AwaitObservable(form.MouseDown)
let downPos = (down.X, down.Y)
if (down.Button &&& MouseButtons.Left) = MouseButtons.Left then
let! upPos = drawingLoop(Color.IndianRed, downPos)
do printfn "Drawn rectangle (%A, %A)" downPos upPos }
这里的好处是,您可以很好地表达逻辑-等待MouseDown
(在waitingLoop
内部),然后调用drawingLoop
函数,等待MouseMove
,直到松开按钮(然后将控件传输回waitingLoop
,它开始等待另一个鼠标按下事件)
类似代码的另一个版本在中
完整的源代码是其中的一部分。这正是我试图实现的。但是我有很多关于异步工作流和f#中不同运算符的知识需要学习。也许你可以用&&&&and let!为我指出正确的方向?
&&&&
是“二进制和”并且let!k=x:Async
正在等待异步操作,然后将k
设置为T
类型的变量(至少在异步{}块中)这正是我想要实现的。但是我还有很多关于异步工作流和f#中的不同操作符的知识要学习。也许你可以用&&&和let!为我指出正确的方向?&&&&&
是“二进制和”并且let!k=x:Async
正在等待异步操作,然后将k
设置为T
类型的变量(至少在异步{}块中)