2010-04-23 66 views
1

鼠标拖动我有以下创建完成观察到与无扩展

var leftMouseDown = Observable.FromEvent<MouseButtonEventArgs>(displayCanvas, "MouseLeftButtonDown"); 
var leftMouseUp = Observable.FromEvent<MouseButtonEventArgs>(displayCanvas, "MouseLeftButtonUp"); 
var mouseMove = Observable.FromEvent<MouseEventArgs>(displayCanvas, "MouseMove"); 

var leftMouseDragging = from down in leftMouseDown 
         let startPoint = down.EventArgs.GetPosition(displayCanvas) 
         from move in mouseMove.TakeUntil(leftMouseUp) 
         let endPoint = move.EventArgs.GetPosition(displayCanvas) 
         select new { Start = startPoint, End = endPoint }; 

,当我订阅它会给我的阻力,当前终点的起点。现在我需要做一些事情,一旦拖动完成。我是在试图做到这一点完全RX失败,结束了做

leftMouseDragging.Subscribe(value=> 
    { 
     dragging = true; 
     //Some other code 
    }); 

leftMouseUp.Subscribe(e=> 
    { 
     if(dragging) 
     { 
      MessageBox.Show("Just finished dragging"); 
      dragging = false; 
     } 
    }); 

,直到我做了鼠标右键拖动这工作得很好。然后当我点击鼠标左键时,我会看到消息框。如果我只是做一个左键拖动,我得到消息框,然后单击鼠标左键不会产生框。我想在没有外部状态的情况下做到这一点,但如果没有其他事情我至少会喜欢它的正常工作。

仅供参考:我试着拖动volatile并使用一个锁,但没有奏效。

编辑

原来,我的问题是用右键点击上下文菜单。一旦我摆脱了我的上面的代码工作。所以,现在我的问题是如何获得上下文菜单,并仍然有我的代码工作。我假设上下文菜单正在处理鼠标左键单击,并以某种方式导致我的代码无法工作,但我仍然困惑它。

+0

我问了一个非常类似的问题:http://stackoverflow.com/questions/2574046/whats-the-best-way-to-structure-this-linq-to-events-drag-drop-code - does sergey的回答有帮助吗? – 2010-04-23 15:57:17

+0

@Rob关闭了,但在我的情况下,我不想知道他们何时只是单击鼠标而不进行拖动,而您的代码会在该位置创建一个椭圆并更改其颜色。我会看看是否可以合并“发布”和“连接”以使其发挥作用。 – juharr 2010-04-23 16:12:39

回答

5

如果拖动是你所需要的,那么简单的.zip工作不会吗? :

var drag = _mouseDown 
    .Select(args => args.EventArgs.GetPosition(canvas)) 
    .Zip(_mouseUp.Select(args => args.EventArgs.GetPosition(canvas)), 
     (p1, p2) => new { p1, p2 }); 
drag.Subscribe(p1p2 => 
     Console.WriteLine(@"({0}:{1})({2}:{3})", 
      p1p2.p1.X, p1p2.p1.Y, p1p2.p2.X, p1p2.p2.Y)); 

您可以应用过滤器在哪里,如果你需要排除长度为零的阻力。

编辑:虽然,邮编是容易释放鼠标窗外 - 在这种情况下,除非你捕捉你没有得到mouseUp事件...... 下面是一个使用只有最新的鼠标按下mouseUp事件之前的版本:

var drag = _mouseDown 
    .Select(args => args.EventArgs.GetPosition(canvas)) 
    .TakeUntil(_mouseUp) 
    .CombineLatest(_mouseUp 
     .Select(args => args.EventArgs.GetPosition(canvas)) 
     .Take(1), (p1, p2) => new { p1, p2 }) 
    .Repeat();