拖动以在 UserControl 上平移
我正在尝试构建自己的“PictureBox like”控件,添加一些功能。例如,我希望能够通过简单地单击并拖动鼠标来平移大图像。
问题似乎出在我的 OnMouseMove 方法上。如果我使用下面的代码,我会得到我想要的拖动速度和精度,但是当然,当我释放鼠标按钮并尝试再次拖动时,图像会恢复到其原始位置。
using System.Drawing;
using System.Windows.Forms;
namespace Testing
{
public partial class ScrollablePictureBox : UserControl
{
private Image image;
private bool centerImage;
public Image Image
{
get { return image; }
set { image = value; Invalidate(); }
}
public bool CenterImage
{
get { return centerImage; }
set { centerImage = value; Invalidate(); }
}
public ScrollablePictureBox()
{
InitializeComponent();
SetStyle(ControlStyles.AllPaintingInWmPaint | ControlStyles.OptimizedDoubleBuffer, true);
Image = null;
AutoScroll = true;
AutoScrollMinSize = new Size(0, 0);
}
private Point clickPosition;
private Point scrollPosition;
protected override void OnMouseDown(MouseEventArgs e)
{
base.OnMouseDown(e);
clickPosition.X = e.X;
clickPosition.Y = e.Y;
}
protected override void OnMouseMove(MouseEventArgs e)
{
base.OnMouseMove(e);
if (e.Button == MouseButtons.Left)
{
scrollPosition.X = clickPosition.X - e.X;
scrollPosition.Y = clickPosition.Y - e.Y;
AutoScrollPosition = scrollPosition;
}
}
protected override void OnPaint(PaintEventArgs e)
{
base.OnPaint(e);
e.Graphics.FillRectangle(new Pen(BackColor).Brush, 0, 0, e.ClipRectangle.Width, e.ClipRectangle.Height);
if (Image == null)
return;
int centeredX = AutoScrollPosition.X;
int centeredY = AutoScrollPosition.Y;
if (CenterImage)
{
//Something not relevant
}
AutoScrollMinSize = new Size(Image.Width, Image.Height);
e.Graphics.DrawImage(Image, new RectangleF(centeredX, centeredY, Image.Width, Image.Height));
}
}
}
但是,如果我将 OnMouseMove 方法修改为如下所示:
protected override void OnMouseMove(MouseEventArgs e)
{
base.OnMouseMove(e);
if (e.Button == MouseButtons.Left)
{
scrollPosition.X += clickPosition.X - e.X;
scrollPosition.Y += clickPosition.Y - e.Y;
AutoScrollPosition = scrollPosition;
}
}
...您会发现拖动不像以前那样平滑,有时表现得很奇怪(例如有滞后或其他原因)。
我做错了什么?
我还尝试删除所有“基地”呼吁,以绝望的运动来解决这个问题,哈哈,但同样,它没有奏效。
感谢您抽出时间。
I'm trying to build my own "PictureBox like" control adding some functionalities. For example, I want to be able to pan over a big image by simply clicking and dragging with the mouse.
The problem seems to be on my OnMouseMove method. If I use the following code I get the drag speed and precision I want, but of course, when I release the mouse button and try to drag again the image is restored to its original position.
using System.Drawing;
using System.Windows.Forms;
namespace Testing
{
public partial class ScrollablePictureBox : UserControl
{
private Image image;
private bool centerImage;
public Image Image
{
get { return image; }
set { image = value; Invalidate(); }
}
public bool CenterImage
{
get { return centerImage; }
set { centerImage = value; Invalidate(); }
}
public ScrollablePictureBox()
{
InitializeComponent();
SetStyle(ControlStyles.AllPaintingInWmPaint | ControlStyles.OptimizedDoubleBuffer, true);
Image = null;
AutoScroll = true;
AutoScrollMinSize = new Size(0, 0);
}
private Point clickPosition;
private Point scrollPosition;
protected override void OnMouseDown(MouseEventArgs e)
{
base.OnMouseDown(e);
clickPosition.X = e.X;
clickPosition.Y = e.Y;
}
protected override void OnMouseMove(MouseEventArgs e)
{
base.OnMouseMove(e);
if (e.Button == MouseButtons.Left)
{
scrollPosition.X = clickPosition.X - e.X;
scrollPosition.Y = clickPosition.Y - e.Y;
AutoScrollPosition = scrollPosition;
}
}
protected override void OnPaint(PaintEventArgs e)
{
base.OnPaint(e);
e.Graphics.FillRectangle(new Pen(BackColor).Brush, 0, 0, e.ClipRectangle.Width, e.ClipRectangle.Height);
if (Image == null)
return;
int centeredX = AutoScrollPosition.X;
int centeredY = AutoScrollPosition.Y;
if (CenterImage)
{
//Something not relevant
}
AutoScrollMinSize = new Size(Image.Width, Image.Height);
e.Graphics.DrawImage(Image, new RectangleF(centeredX, centeredY, Image.Width, Image.Height));
}
}
}
But if I modify my OnMouseMove method to look like this:
protected override void OnMouseMove(MouseEventArgs e)
{
base.OnMouseMove(e);
if (e.Button == MouseButtons.Left)
{
scrollPosition.X += clickPosition.X - e.X;
scrollPosition.Y += clickPosition.Y - e.Y;
AutoScrollPosition = scrollPosition;
}
}
... you will see that the dragging is not smooth as before, and sometimes behaves weird (like with lag or something).
What am I doing wrong?
I've also tried removing all "base" calls on a desperate movement to solve this issue, haha, but again, it didn't work.
Thanks for your time.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
最后,我设法找到了解决方案:
Finally, I managed to find a solution:
每次我必须这样做时,这总是令人困惑。
为了那些新到达此线程的人的利益,我想出了一个稍微简单的解决方案,可以实现平滑的平移。
顺便说一句,抓取和抓取手形光标可以从以下位置下载:
http://theburningmonk.com/2010/ 03/wpf-loading-grab-and-grabbing-cursors-from-resource/
您可以将它们作为嵌入式资源添加到您的项目中,并设置它们:
This is always confusing every time I have to do it.
For the benefit of those newly arriving to this thread I came up with a slightly simpler solution that gives smooth panning.
By the way, the grab and grabbing hand cursors can be downloaded from:
http://theburningmonk.com/2010/03/wpf-loading-grab-and-grabbing-cursors-from-resource/
You can add them to your project as embedded resources and set them with: