2016-08-15 165 views
3

我正在一个小应用程序中绘制矩形并用鼠标移动它们。用鼠标移动矩形的C#bug

我有一些逻辑里面有一些错误,我找不到它们。

首先单击并拖动总是穿绕位置(0,0)的矩形,第二次点击和拖动将工作得很好。

第三次单击将再次将矩形放在(0,0)上,然后用第四次单击我可以再次拖动它。

using System; 
using System.Collections.Generic; 
using System.ComponentModel; 
using System.Data; 
using System.Drawing; 
using System.Linq; 
using System.Text; 
using System.Threading.Tasks; 
using System.Windows.Forms; 

namespace Pr 
{ 
    public partial class Form1 : Form 
    { 
     int save=0; 
     Timer timer1 = new Timer(); 
     private Point MouseDownLocation; 

     private List<Rectangle> rectangles; 

     public Form1() 
     { 
      InitializeComponent(); 
      rectangles = new List<Rectangle>(); 
      panel1.Paint += panel1_Paint; 
      this.DoubleBuffered = true; 
      timer1.Interval = 10; 
      timer1.Start(); 
     } 

     private void timer1_Tick(object sender, EventArgs e) 
     { 
      Refresh(); 
     } 

     public void PopulateTable(int x, int y) 
     { 
      rectangles.Add(new Rectangle (500, 10, x, y)); 
      panel1.Invalidate(); 
     } 

     void panel1_Paint(object sender, PaintEventArgs e) 
     { 
      foreach(var rectangle in rectangles) 
      { 
       using (var b=new SolidBrush(Color.HotPink)) 
       { 
        e.Graphics.FillRectangle(b, rectangle); 
       } 
      } 
     } 

     private void Form1_Load(object sender, EventArgs e) 
     { 
      this.WindowState = FormWindowState.Maximized; 
      this.MinimumSize = this.Size; 
      this.MaximumSize = this.Size; 
     } 

     private void panel1_MouseMove(object sender, MouseEventArgs e) 
     { 
      if (e.Button == MouseButtons.Left) 
      { 
       for (var i = 0; i < rectangles.Count; i++) 
       { 
        if (Cursor.Position.X >= rectangles[i].X && 
         Cursor.Position.X <= rectangles[i].X + rectangles[i].Width && 
         Cursor.Position.Y >= rectangles[i].Y && 
         Cursor.Position.Y <= rectangles[i].Y + rectangles[i].Height) 
        { 
         save = i; 
         Rectangle rect = rectangles[save]; 
         rect.X = e.X - MouseDownLocation.X; 
         rect.Y = e.Y - MouseDownLocation.Y; 

         rectangles[save] = rect; 
         panel1.Invalidate(); 
         break; 
        } 
       } 
      } 
     } 

     protected void panel1_OnMouseDown(object sender, MouseEventArgs e) 
     { 
      if (e.Button == MouseButtons.Left) 
       MouseDownLocation = e.Location; 
     } 

     private void panel2_Paint(object sender, PaintEventArgs e) 
     { 
     } 

     private void label1_Click(object sender, EventArgs e) 
     { 
     } 

     private void button1_Click(object sender, EventArgs e) 
     { 
      PopulateTable(Convert.ToInt32(textBox1.Text), Convert.ToInt32(textBox2.Text)); 
     } 
    } 
} 

我敢打赌,我的移动逻辑不太好,所以我希望有人会提出一些想法。

编辑: 我只是改变

rect.X = e.X - MouseDownLocation.X; 
rect.Y = e.Y - MouseDownLocation.Y; 

rect.X = e.X; 
rect.Y = e.Y; 

它工作得更好,但我有一个问题。

当我点击时,矩形会移动,以便矩形的左上角位于鼠标位置。

我想让它保持在相同的位置,除非我移动它。

EDIT 2

我改变了部分代码:

rect.X = rect.X + e.X - MouseDownLocation.X; 
rect.Y = rect.Y + e.Y - MouseDownLocation.Y; 

但是,现在的矩形移动太快,它会比鼠标要快得多。

这可能是定时器的问题吗?

EDIT 3

MouseDownLocatioon必须的问题。如果没有它的代码有效(矩形在鼠标坐标上移动),那意味着有什么问题。

试图这样做:

protected void panel1_OnMouseDown(object sender, MouseEventArgs e) 
     { 
      if (e.Button == MouseButtons.Left) 
       MouseDownLocation = panel1.PointToScreen(e.Location); 
     } 

没有帮助。

试过调试,看起来像Y坐标有问题。它只是在Y坐标上产生很大的偏移量。

我做了一个鼠标移动从左至右(仅X坐标),和调试表明我:

rect.X = 500

rect.Y = 100

的eX = 848

e。Y = 216

MouseDownLocation.X = 850

MouseDownLocation.Y = 238

这意味着对于这种举动差异仅是为了×2,和y的22!

编辑4:管理解决它!

只需要添加两行代码:

MouseDownLocation.X = e.X; 
MouseDownLocation.Y = e.Y; 

因为,如果我按住鼠标按钮,它不会刷新新MouseDownLocation。

+0

请注意,矩形有(除其他外)一个很好的包含(点)功能!还要注意Cursor.Position是在屏幕坐标中,而不是在Mousexxxevents中获得的相对值!有两个方向的转换功能:Control.PointToClient和Control.PointToScreen – TaW

+0

感谢,@TaW在您的评论。这就是为什么我把面板(0,0),所以我不必改变 – omicito

+0

屏幕真的是屏幕,而不是形式!更好的做它真的是正确的,而不是扭曲你的布局;-) – TaW

回答

1
rect.X = e.X - MouseDownLocation.X; 
rect.Y = e.Y - MouseDownLocation.Y; 

我还不能肯定是什么MouseDownLocation是,而是基于名字,当你第一次开始移动框,当前位置(e.X,e.Y)等于MouseDownLocation,这意味着你的数学工程以(0,0) 。这似乎是你为什么走到角落的原因。

从技术上讲,你是第二次和第四次点击也是这样做的,但既然你已经在角落里,这是不明显的。

编辑您的编辑矩形现在将角落移动到您的光标: 当您单击鼠标时,您需要计算并存储从矩形位置到鼠标的偏移量,然后使用该偏移量MouseMove事件处理程序。

+0

我很抱歉,看起来像我没有复制/粘贴的一部分码。 MouseDownLocation给出了按下游标时的位置 – omicito

+0

@omicito我觉得这是这种效果。我也在编辑中加入了一些关于答案的想法。 –

+0

是的,我做了这样的事情,但现在我遇到了一些新问题。这是我的新编辑。 并感谢@泰勒 – omicito