2015-07-10 67 views
1

此代碼只是POC,「用WPF編寫」,但如果將事件處理函數更改爲winforms函數,則幾乎相同的事情將應用於Winforms ...只是試圖獲取邏輯,然後我將其生成它。無法獲得此鼠標檢測代碼可靠工作...任何想法?

我想要做的是檢測拖動操作鼠標方向的變化。因此,例如,點擊表格的客戶區域上的&,然後將鼠標移動到右側,現在將其移動到左側......這將是方向更改。同樣的事情,顯然離開< - >右,右< - >左,上< - >下來,下來< - >起來......對角線向右上方< - >對角線左下等

我我已經嘗試了幾種不同的概念,而我沒有的概念似乎最好,但它仍然有點不可靠......我得到了一些誤報和一些失誤。這個代碼做的想法是保存10個點的鼠標移動,然後計算第一個點和最後一個點之間的線的角度,然後如果我得到相反方向的下一個段,那將是一個改變。它有點/有些作品,但我把可靠性放在了75%。不可靠性似乎是,如果你做了類似於左上對角線,然後上下來回移動,它不會可靠地檢測到上下方向的變化。

我沒有結婚的念頭角度...它只是我已經得到了最好的工作,到目前爲止..這裏是最少的代碼:

using System; 
using System.Collections.Generic; 
using System.Windows; 
using System.Windows.Input; 

namespace WpfApplication7 
{ 
    public partial class MainWindow : Window 
    { 
     public MainWindow() 
     { 
      InitializeComponent(); 

      MouseLeftButtonDown += MainWindow_MouseLeftButtonDown; 
      MouseLeftButtonUp += MainWindow_MouseLeftButtonUp; 
      MouseMove += MainWindow_MouseMove; 
     } 

     Point _pt; 
     List<Point> lst = new List<Point>(); 
     double? _d = null; 

     void MainWindow_MouseMove(object sender, MouseEventArgs e) 
     { 
      if (Mouse.Captured == this) 
      { 
       lst.Add(e.GetPosition(this)); 

       if (lst.Count >= 10) 
       { 
        double dX = lst[lst.Count - 1].X - lst[0].X; 
        double dY = lst[lst.Count - 1].Y - lst[1].Y; 

        double dAngle = Math.Atan2(dY, dX) * 180/Math.PI; 

        //System.Diagnostics.Debug.WriteLine("GOT ANGLE: " + dAngle); 

        if (!_d.HasValue) 
        { 
         _d = dAngle; 
        } 
        else 
        { 
         //System.Diagnostics.Debug.WriteLine(Math.Abs(dAngle - _d.Value)); 

         if (Math.Abs(dAngle - _d.Value) >= 160.0 && Math.Abs(dAngle - _d.Value) <= 200) 
         { 
          System.Diagnostics.Debug.WriteLine(DateTime.Now + " DIRECTION CHANGE!"); 
          _d = dAngle; 
         } 

         _d = dAngle; 
        } 

        lst.Clear(); 
       } 
      } 
     } 

     void MainWindow_MouseLeftButtonUp(object sender, MouseButtonEventArgs e) 
     { 
      ReleaseMouseCapture(); 
     } 

     void MainWindow_MouseLeftButtonDown(object sender, MouseButtonEventArgs e) 
     { 
      lst.Clear(); 
      _d = null; 
      _pt = e.GetPosition(this); 
      CaptureMouse(); 
     } 
    } 
} 
+0

不確定關注...你會如何?用兩點並排檢測方向?你不會得到一條水平線,一條垂直線還是一條「45度」線?另外,從我的實驗中,我注意到,由於移動鼠標的人顯而易見,數據中存在「噪音」。另一個問題是......當你沿對角線移動時,你總是無法在同一個事件中同時發生X和Y變化......有時它會變成2+。 – SledgeHammer

+0

我認爲您應該在某個時間點對變量_pt進行比較,因爲這是您的拖放請求的起源,我沒有看到它在您的計算中使用。 –

+0

對不起,我刪除了我原來的問題,但我不確定爲什麼你會捕獲最後的10個動作,然後只對它進行比較(這實際上是你在做什麼,因爲你只是對最後一個起點進行計算10和最新的位置在理論上,你可以在清除清單後改變點0的方向,只要清單的持續時間在同一方向上繼續改變,那麼比較就是有效的,這是否有意義? –

回答

0

我懷疑下面的代碼

double dX = lst[lst.Count - 1].X - lst[0].X; 
double dY = lst[lst.Count - 1].Y - lst[1].Y; 

應改爲:

double dX = lst[lst.Count - 1].X - _pt.X; 
double dY = lst[lst.Count - 1].Y - _pt.Y; 

我的理由是這樣的:你正在閱讀過去10位置(0,1),(0,2),(0,3),(0,4),(0,5),(0,6),(0,7) ,(0,8),(0,9),(0,10)

然後運行比較並清除列表。但是,如果光標在列表清除時向相反的方向移動,則檢測將被忽略,因爲它仍然是連續的: (0,10),(0,9),(0,8),(0,7 ),(0,6),(0,5),(0,4),(0,3),(0,2),(0,1)

+0

其實這並不是答案,我只是在一個控制檯應用程序中運行這個程序,當我沿着一個座標軸(在這個例子中是y)順序執行時發現了這個變化。當我順序走,在兩個軸上,然後倒轉,方向被錯過。這在上面提供的片段中都是如此。它可能與檢測變化的功能有關,但我的觸發器真的生鏽,所以我可以沒有幫助 –

+0

我不計算對_pt的角度,因爲這是點擊點。因此,如果我點擊0,0然後移動到100,0,它將不會檢測到方向變化,直到它至少跨越0,0到-1,0。 – SledgeHammer