winforms - 拖动以在 UserControl 上平移

标签 winforms user-controls c#-2.0 picturebox panning

我正在尝试构建自己的“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;
    }
}

...你会发现拖动不像以前那样平滑,有时表现得很奇怪(比如有滞后或其他什么)。

我做错了什么?

我还尝试删除所有“基地”呼吁,以绝望的运动来解决这个问题,哈哈,但同样,它没有奏效。

感谢您的宝贵时间。

最佳答案

最后,我设法找到了解决方案:

protected Point clickPosition;
protected Point scrollPosition;
protected Point lastPosition;

protected override void OnMouseDown(MouseEventArgs e)
{
    clickPosition.X = e.X;
    clickPosition.Y = e.Y;
}

protected override void OnMouseUp(MouseEventArgs e)
{
    Cursor = Cursors.Default;
    lastPosition.X = AutoScrollPosition.X;
    lastPosition.Y = AutoScrollPosition.Y;
}

protected override void OnMouseMove(MouseEventArgs e)
{
    if (e.Button == MouseButtons.Left)
    {
        Cursor = Cursors.Hand;
        scrollPosition.X = clickPosition.X - e.X - lastPosition.X;
        scrollPosition.Y = clickPosition.Y - e.Y - lastPosition.Y;
        AutoScrollPosition = scrollPosition;
    }
}

关于winforms - 拖动以在 UserControl 上平移,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2675194/

相关文章:

c# - NumericUpDown 背景色未按预期工作

c# - NHibernate 对象 ID 返回不正确的值

c# - 我可以在 winform 中可靠地使用 WPF 自定义控件吗?

c# - TextBox 最大字符数(不是 MaxLength)

c# - UserControl 作为界面,但在设计器中可见

c# - 暴露底层控制的事件

interop - 如何从word文档中提取项目符号信息?

c# - 多维数组列表 C#

.net - WinForms 中的右对齐标签

sql-server - C# SQL 连接字符串最佳实践