Drag and Drop in Silverlight with F# and Asynchronous Workflows

白昼怎懂夜的黑 提交于 2019-12-06 04:22:58

The way to solve this issue is to use an overloaded AwaitEvent that allows you to wait for two events. Instead of just waiting for MouseMove, you can also wait for the MouseUp event - in the first case, you can continue moving and in the second case, you can return from the loop and stop drag&drop (this is actually discussed later in the book in section 16.4.5).

Here is the code - it actually uses AwaitObservable variant of the method (see below), which is a better choice in general, because it works with Observable.map and similar combinators (in case you wanted to use these).

let! args = Async.AwaitObservable(layoutRoot.MouseMove, layoutRoot.MouseUp)
match args with
| Choice1Of2(args) ->
    // Handle the 'MouseMove' event with 'args' here
    Canvas.SetLeft(rectangle1, args.GetPosition(layoutRoot).X)  
    Canvas.SetTop(rectangle1, args.GetPosition(layoutRoot).Y)  
    return! drag()  
| Choice2Of2(_) ->
    // Handle the 'MouseUp' event here
    return()  

As far as I know, the overloaded AwaitObservable method is not available in the F# libraries (yet), but you can get it from the book's web site, or you can use the following code:

// Adds 'AwaitObservable' that takes two observables and returns
// Choice<'a, 'b> containing either Choice1Of2 or Choice2Of2 depending
// on which of the observables occurred first
type Microsoft.FSharp.Control.Async with   
  static member AwaitObservable(ev1:IObservable<'a>, ev2:IObservable<'b>) = 
    Async.FromContinuations((fun (cont,econt,ccont) -> 
      let rec callback1 = (fun value ->
        remover1.Dispose()
        remover2.Dispose()
        cont(Choice1Of2(value)) )
      and callback2 = (fun value ->
        remover1.Dispose()
        remover2.Dispose()
        cont(Choice2Of2(value)) )
      // Attach handlers to both observables
      and remover1 : IDisposable  = ev1.Subscribe(callback1) 
      and remover2 : IDisposable  = ev2.Subscribe(callback2) 
      () ))
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!