views:

89

answers:

1

I found Customize a panel with Autoscroll property at http://www.codeproject.com/KB/miscctrl/CustomAutoScrollPanel.aspx that is wrapper around a Panel with AutoScroll = True.

I like this control because it provides the "performScrollHorizontal" and "performScrollVertical" methods. Yet, it uses the Windows API functions instead of ScrollableControl and its VerticalScroll and HorizontalScroll properties.

Is this a good control to use? I think it should be using ScrollableControl instead of the Windows API. What do you think? Is there a better control available? Do I even need a control? I would think that ScrollableControl provides everything I would need.

EDIT: I found the HScrollBar and VScrollBar controls. Should I be using them?

These two other controls are nice but do not give me a way to control the scroll bars like the above control does.

What I really want is a control:

  • that scrolls when the user moves the mouse toward the edge of the control,
  • allows the user to pan
  • allows the user to zoom
  • supports using the mouse with Shift or Ctrl or Alt keys pressed

Any recommendations, help, or areas to look at is greatly appreciated. A control would be nice as I am not that good yet.

+2  A: 

Some code to play with. It supports focus, panning and scrolling. Zooming is work-to-do, my laptop's mousepad got in the way of testing it. Use a timer to implement auto-scrolling at the edges.

using System;
using System.Drawing;
using System.Windows.Forms;

class ZoomPanel : Panel {
    public ZoomPanel() {
        this.DoubleBuffered = true;
        this.SetStyle(ControlStyles.Selectable, true);
        this.SetStyle(ControlStyles.ResizeRedraw, true);
        this.AutoScroll = this.TabStop = true;
    }
    public Image Image {
        get { return mImage; }
        set { 
            mImage = value; 
            Invalidate();
            mZoom = 1.0;
            this.AutoScrollMinSize = (mImage != null) ? mImage.Size : Size.Empty;
        }
    }
    protected override void OnMouseDown(MouseEventArgs e) {
        if (e.Button == MouseButtons.Left) {
            this.Cursor = Cursors.SizeAll;
            mLastPos = e.Location;
            this.Focus();
        }
        base.OnMouseDown(e);
    }
    protected override void OnMouseUp(MouseEventArgs e) {
        if (e.Button == MouseButtons.Left) this.Cursor = Cursors.Default;
        base.OnMouseUp(e);
    }
    protected override void OnMouseMove(MouseEventArgs e) {
        if (e.Button == MouseButtons.Left) {
            this.AutoScrollPosition = new Point(
                -this.AutoScrollPosition.X - e.X + mLastPos.X,
                -this.AutoScrollPosition.Y - e.Y + mLastPos.Y);
            mLastPos = e.Location;
            Invalidate();
        }
        base.OnMouseMove(e);
    }
    protected override void OnMouseWheel(MouseEventArgs e) {
        if (mImage != null) {
            mZoom *= 1.0 + 0.3 * e.Delta / 120;
            this.AutoScrollMinSize = new Size((int)(mZoom * mImage.Width),
                (int)(mZoom * mImage.Height)); \
            // TODO: calculate new AutoScrollPosition...
            Invalidate();
        }
        base.OnMouseWheel(e);
    }
    protected override void OnPaint(PaintEventArgs e) {
        if (mImage != null) {
            var state = e.Graphics.Save();
            e.Graphics.TranslateTransform(this.AutoScrollPosition.X, this.AutoScrollPosition.Y);
            e.Graphics.DrawImage(mImage, 
                new Rectangle(0, 0, this.AutoScrollMinSize.Width, this.AutoScrollMinSize.Height));
            e.Graphics.Restore(state);
        }
        //if (this.Focused) ControlPaint.DrawFocusRectangle(e.Graphics,
        //    new Rectangle(0, 0, this.ClientSize.Width, this.ClientSize.Height));
        base.OnPaint(e);
    }
    protected override void OnEnter(EventArgs e) { Invalidate(); base.OnEnter(e); }
    protected override void OnLeave(EventArgs e) { Invalidate(); base.OnLeave(e); }

    private double mZoom = 1.0;
    private Point mLastPos;
    private Image mImage;
}
Hans Passant
How would I use a timer. I don't know where I would begin. Thanks.
Fred F.
Sounds like a good question for a new thread.
Hans Passant