2015-07-10 69 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