拖动表单会向下移动表单

时间:2016-07-14 09:16:24

标签: c# windows

我有一个Windows窗体,我的任务是向窗体添加拖动功能。 “VendorMasterList”是一个标签。我已将鼠标移动,鼠标按下和鼠标移动事件添加到该标签。

enter image description here

如果我试图拖动,表单向下移动然后只能拖动我想要的方式。我的问题是为什么它会下降?这是我的代码

   private Point startPoint = new Point(0, 0);
   private bool isDragging = false;

   private void lblHeader_MouseDown(object sender, MouseEventArgs e)
    {
       isDragging = true;  // _dragging is your variable flag
       startPoint = new Point(e.X, e.Y);
    }
    private void lblHeader_MouseUp(object sender, MouseEventArgs e)
    {
       isDragging = false;
    }
     private void lblHeader_MouseMove(object sender, MouseEventArgs e)
    {
        if (isDragging)
            {
                Point p = PointToScreen(e.Location);
                this.Location = new Point(p.X - this.startPoint.X, p.Y - this.startPoint.Y);
            }
     }

有什么方法可以解决这个问题吗?

新增图片

enter image description here

1 个答案:

答案 0 :(得分:0)

我没有'尝试过你的代码,但我看到的只是部分正确: - )

您保存初始坐标,该坐标相对于单击控件的左上角,但您需要保存屏幕坐标。< / p>

然后移动鼠标并再次获得相对于该角落的点。你错过了一些相关的事情:

  1. 您需要根据屏幕坐标计算两点之间的差值,否则移动光标下方的窗口会给出错误的值。
  2. 您需要将此增量添加到表单的当前位置
  3. 您需要保存新的鼠标位置才能正确计算下一个增量
  4. 可以通过Cursor.Position获得基于屏幕坐标的当前鼠标位置。

    所以你的代码应该是:

    private void lblHeader_MouseDown(object sender, MouseEventArgs e)
    {
       isDragging = true;  // _dragging is your variable flag
       startPoint = Cursor.Position;
    }
    
    private void lblHeader_MouseUp(object sender, MouseEventArgs e)
    {
       isDragging = false;
    }
    
    private void lblHeader_MouseMove(object sender, MouseEventArgs e)
    {
        if (isDragging)
        {
            Point p = Cursor.Position;
            int deltaX = p.X - startPoint.X;
            int deltaY = p.Y - startPoint.Y;
            startPoint = p;
    
            this.Left += deltaX;
            this.Top += deltaY;
        }
     }
    

    我只是在表单上放置了一个面板并实现了上面的工作。

    @IInspector是正确的,他说这种方法实际上不是很好,因为它没有考虑到Windows实际上可以为你处理所有这些。

    我采取的另一种方法(也是更好的方法)是:

    1. 覆盖WndProc方法,如下所示
    2. 完成。不再需要处理鼠标了
    3. 以下是如何覆盖WndProc以满足您的需求的示例:

      protected override void WndProc(ref Message m)
      {
          const UInt32 WM_NCHITTEST = 0x0084;
          const UInt32 HTCAPTION = 0x2;
      
          bool handled = false;
          if (m.Msg == WM_NCHITTEST)
          {
              if (<cursor is within the caption area>)
              {
                  m.Result = (IntPtr)HTCAPTION;
                  handled = true;
              }
          }
      
          if (!handled)
              base.WndProc(ref m);
      }
      

      要限制可以移动窗口的区域,可以使用以下方法。当然,@ IInspectable会不同意,但是你走了这条路: - )

      private void lblHeader_MouseMove(object sender, MouseEventArgs e)
      {
          if (isDragging)
          {
              Point p = Cursor.Position;
              int deltaX = p.X - startPoint.X;
              int deltaY = p.Y - startPoint.Y;
              startPoint = p;
      
              int fX = this.Left + deltaX;
              int fY = this.Top + deltaY;
      
              if (fX >= 0 && fX + this.Width < Area.Width) this.Left = fX;
              if (fY >= 0 && f> + this.Height < Area.Height) this.Top = fY;
          }
       }