2010-04-23 67 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();