Panning weirdness on an UserControl
        Posted  
        
            by Matías
        on Stack Overflow
        
        See other posts from Stack Overflow
        
            or by Matías
        
        
        
        Published on 2010-04-20T12:50:54Z
        Indexed on 
            2010/04/20
            12:53 UTC
        
        
        Read the original article
        Hit count: 514
        
Hello,
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.
© Stack Overflow or respective owner