C# 在面板周围拖动控件
Posted
技术标签:
【中文标题】C# 在面板周围拖动控件【英文标题】:C# drag controls around a panel 【发布时间】:2013-08-22 03:04:26 【问题描述】:我正在开发一个允许用户在同一个面板中拖动对象的系统,我经过一些研究发现我应该使用鼠标事件,如 mouse_up、mouse_down 和 mouse_move。
该程序将生成 3 个图片框并允许用户在面板内的每个图片框周围拖动,但我编写的程序无法完美运行,因为当我拖动图片框时,图片框会移动,但不是根据我的鼠标光标位置,它在其他地方,此外,在拖动时,面板中有图片框阴影,我尝试过那些 update()、refresh() 和 invalidate(),但它似乎对我没有用。以下是我的代码,感谢您的帮助
public partial class Form1 : Form
List<PictureBox> pictureBoxList = new List<PictureBox>();
private bool isDragging = false;
public Form1()
InitializeComponent();
for (int i = 0; i < 3; i++)
PictureBox picture = new PictureBox
Name = "pictureBox" + i,
Size = new Size(20, 20),
Location = new Point(i * 40, i * 40),
BorderStyle = BorderStyle.FixedSingle,
SizeMode = PictureBoxSizeMode.Zoom,
ImageLocation = "A.jpg"
;
pictureBoxList.Add(picture);
foreach (PictureBox p in pictureBoxList)
p.MouseDown += new MouseEventHandler(c_MouseDown);
p.MouseMove += new MouseEventHandler(c_MouseMove);
p.MouseUp += new MouseEventHandler(c_MouseUp);
pnlDisplayImage.Controls.Add(p);
pnlDisplayImage.Refresh();
void c_MouseDown(object sender, MouseEventArgs e)
isDragging = true;
void c_MouseMove(object sender, MouseEventArgs e)
if (isDragging == true)
Control c = sender as Control;
for (int i = 0; i < pictureBoxList.Count(); i++)
if (c.Equals(pictureBoxList[i]))
pictureBoxList[i].Location = new Point(e.X, e.Y);
void c_MouseUp(object sender, MouseEventArgs e)
PictureBox c = sender as PictureBox;
isDragging = false;
for (int i = 0; i < pictureBoxList.Count(); i++)
if (c.Equals(pictureBoxList[i]))
pictureBoxList[i].Location = new Point(e.X, e.Y);
private void pnlDisplayImage_Paint(object sender, PaintEventArgs e)
foreach (PictureBox p in pictureBoxList)
pnlDisplayImage.Controls.Add(p);
【问题讨论】:
【参考方案1】:最后我找到了导致我的程序没有按预期运行的问题。主要问题是我不小心将foreach循环放在了我用来创建pictureBox的for循环中,这个问题导致pictureBox在运行时出现一些阴影效果,因为相同的pictureBox很少。此外,我更改了一些代码,现在它按我的预期运行。以下是我想要回答的代码。
public partial class Form1 : Form
List<PictureBox> pictureBoxList = new List<PictureBox>();
private bool isDragging = false;
Point move;
public Form1()
InitializeComponent();
for (int i = 0; i < 3; i++)
PictureBox picture = new PictureBox
Name = "pictureBox" + i,
Size = new Size(20, 20),
Location = new Point(i * 40, i * 40),
BorderStyle = BorderStyle.FixedSingle,
SizeMode = PictureBoxSizeMode.Zoom,
ImageLocation = "A.jpg"
;
pictureBoxList.Add(picture);
foreach (PictureBox p in pictureBoxList)
p.MouseDown += new MouseEventHandler(c_MouseDown);
p.MouseMove += new MouseEventHandler(c_MouseMove);
p.MouseUp += new MouseEventHandler(c_MouseUp);
pnlDisplayImage.Controls.Add(p);
pnlDisplayImage.Refresh();
void c_MouseDown(object sender, MouseEventArgs e)
Control c = sender as Control;
isDragging = true;
move = e.Location;
void c_MouseMove(object sender, MouseEventArgs e)
if (isDragging == true)
Control c = sender as Control;
for (int i = 0; i < pictureBoxList.Count(); i++)
if (c.Equals(pictureBoxList[i]))
pictureBoxList[i].Left += e.X - move.X;
pictureBoxList[i].Top += e.Y - move.Y;
void c_MouseUp(object sender, MouseEventArgs e)
isDragging = false;
【讨论】:
【参考方案2】:尝试类似(它是带有覆盖的自定义控件,但应该很容易转换为事件):
private bool _isMoved = false; // true if move mode on
private Point _pointMove = new Point(0); // for moving
protected override void OnMouseDown(MouseEventArgs e)
// if left button pressed
if(e.Button == MouseButtons.Left)
_pointMove.X = e.X;
_pointMove.Y = e.Y;
_isMoved = true;
Cursor = Cursors.SizeAll;
Capture = true;
base.OnMouseDown (e);
protected override void OnMouseUp(MouseEventArgs e)
// if move mode on
if(_isMoved)
_isMoved = false;
Cursor = Cursors.Default;
Capture = false;
base.OnMouseUp (e);
protected override void OnMouseMove(MouseEventArgs e)
// if move mode on
if (_isMoved)
Left += e.X - _pointMove.X;
Top += e.Y - _pointMove.Y;
base.OnMouseMove (e);
【讨论】:
嗨 Sinatr,感谢您的回答,我尝试将您给定的代码转换为我的案例,它给了我相同的结果,只是鼠标光标改变了。我在想是不是我的 pnlDisplayImage_Paint 事件导致了问题以上是关于C# 在面板周围拖动控件的主要内容,如果未能解决你的问题,请参考以下文章