如何限制在面板内拖动图像?

How to limit dragging an image inside a Panel?

晚上好。我目前正在开发交互式地图编辑器。我试图通过使用此代码来防止地图图像被拖出视图

        if (currentPosition.X > 0)
            currentPosition.X = 0;
        else if (currentPosition.X <  -mapSize.Width + Size.Width )
            currentPosition.X =  -mapSize.Width + Size.Width ;
        if (currentPosition.Y > 0)
            currentPosition.Y = 0;
        else if (currentPosition.Y < -mapSize.Height + Size.Height)
             currentPosition.Y = -mapSize.Height + Size.Height;

但是我不能把它拖到极限Size-mapSize。 currentPosition 对应于图像的左上角位置。这是 class

的完整代码
namespace GameMaps
{
public class MapPanel : Panel
{
    private Bitmap shownMap = null;
    private Point mapLocation;
    private Size mapSize;
    private bool dragging;
    private Point currentPosition;
    //private Point newPosition;
    private Point initialPosition;
    private Point initialMousePosition;
    private Form1 parentForm;

    public MapPanel(Form1 parentForm) : base()
    {
        this.DoubleBuffered = true;


        this.parentForm = parentForm;

    }
    public MapPanel(Panel targetPanel) : this(new Form1())
    {

    }

    public void ShowMap(Map map)
    {
        if (map == null) return;
        shownMap = map.MapTexture;
        mapLocation = new Point(0, 0);
        mapSize = shownMap.Size;
        currentPosition = new Point();
        initialPosition = new Point();
        initialMousePosition = new Point(); //mapLocation; 

    }
    protected override void OnPaint(PaintEventArgs e)
    {
        e.Graphics.PageUnit = GraphicsUnit.Pixel;
        e.Graphics.PageScale = 1.0F;
        // base.OnPaint(e);
        if (shownMap == null)
        {
            base.OnPaint(e);
            return;
        }
        e.Graphics.DrawImage(shownMap, currentPosition.X, currentPosition.Y);

    }
    protected override void OnMouseDown(MouseEventArgs e)
    {
        // base.OnMouseDown(e);
        if (shownMap == null)
        {
            base.OnMouseDown(e);
            return;
        }
        if (dragging)
        {
            dragging = false;
            return;
        }
        else dragging = true;
        initialPosition.X = currentPosition.X;
        initialPosition.Y = currentPosition.Y;

        initialMousePosition = e.Location;
    }
    protected override void OnMouseMove(MouseEventArgs e)
    {
        /*parentForm.label7.Text = currentPosition.X.ToString();
        parentForm.label8.Text = currentPosition.Y.ToString();
        parentForm.label9.Text = mapSize.Width.ToString();
        parentForm.label10.Text = mapSize.Height.ToString();
        parentForm.label11.Text = Size.Width.ToString();
        parentForm.label12.Text = Size.Width.ToString();*/

        //base.OnMouseMove(e);
        if (!dragging) return;

        currentPosition.X = e.X - initialMousePosition.X + initialPosition.X;
        currentPosition.Y = e.Y - initialMousePosition.Y + initialPosition.Y;

        if (currentPosition.X > 0)
            currentPosition.X = 0;
        else if (currentPosition.X <  -mapSize.Width + Size.Width )
            currentPosition.X =  -mapSize.Width + Size.Width ;
        if (currentPosition.Y > 0)
            currentPosition.Y = 0;
        else if (currentPosition.Y < -mapSize.Height + Size.Height)
             currentPosition.Y = -mapSize.Height + Size.Height;

        //if (currentPosition.X + mapSize.Width < this.Size.Width)
          //  currentPosition.X = this.Size.Width - mapSize.Width;


        Invalidate(); 

     //   (e.X - initialPosition.X + xinit, e.Y - init_loc.Y + yinit);
    }
    protected override void OnMouseLeave(EventArgs e)
    {
        // base.OnMouseLeave(e);
        dragging = false;
        // F*! if I hold the mouse down this does not work
    }

    protected override void OnMouseUp(MouseEventArgs e)
    {
        //base.OnMouseUp(e);
        dragging = false;
    }
}

}

好吧,除了我使用面板的大小而不是它的 DisplayRectangle (Size.Width == DisplayRectangle.Width-2) 之外,似乎没有什么不好的逻辑。整个问题是我使用的图像是从 Photoshop 导出的,分辨率为 72dpi 而不是 96dpi:相同大小,但在使用 DrawImage 时它们被放大了。这是我的解决方案。仍然有这个需要纠正,但这是关于我原来的问题的解决方案。还更改了一些变量名称。

namespace GameMaps
{
public class MapPanel : Panel
{
    private Map sourceMap;

    private Bitmap mapTexture;
    private Size mapSize;
    private Point mapPosition;
    private float dpiX, dpiY;

    private Point initialPosition;
    private Point initialMousePosition;

    private bool dragging;

    /* Constructors */
    public MapPanel() : base()
    {
        this.DoubleBuffered = true;

        this.sourceMap = null;
        this.dpiX = 96.0F; this.dpiY = 96.0F; // For now, this Application won't be DPI aware
    }

    public MapPanel(Panel targetPanel) : this()
    {
        // TO DO
    }

    /* Show a Map */
    public void ShowMap(Map map)
    {
        if (map == null)
            return;
        sourceMap = map;

        mapTexture = new Bitmap(map.MapTexture);
        mapTexture.SetResolution(dpiX, dpiY);
        mapSize = mapTexture.Size; // ?
        mapPosition = new Point(0, 0);
    }

    protected override void OnPaint(PaintEventArgs e)
    {
        // base.OnPaint(e);

        e.Graphics.PageUnit = GraphicsUnit.Pixel; // ?
        e.Graphics.PageScale = 1.0F; // ?

        if (sourceMap == null)
        {
            base.OnPaint(e);
            return;
        }
        e.Graphics.DrawImage(mapTexture, mapPosition.X, mapPosition.Y);
    }

    protected override void OnMouseDown(MouseEventArgs e)
    {
        // base.OnMouseDown(e);

        if (sourceMap == null)
        {
            base.OnMouseDown(e);
            return;
        }

        if (dragging)
        {
            dragging = false;
            return;
        }
        else dragging = true;

        initialPosition.X = mapPosition.X;
        initialPosition.Y = mapPosition.Y;

        initialMousePosition.X = e.Location.X;
        initialMousePosition.Y = e.Location.Y;
    }

    protected override void OnMouseMove(MouseEventArgs e)
    {
        //base.OnMouseMove(e);

        if (!dragging) return;

        mapPosition.X = e.X - initialMousePosition.X + initialPosition.X;
        mapPosition.Y = e.Y - initialMousePosition.Y + initialPosition.Y;

        if (mapPosition.X > 0)
            mapPosition.X = 0;
        else if (mapPosition.X < DisplayRectangle.Width - mapSize.Width)
            mapPosition.X = DisplayRectangle.Width - mapSize.Width;

        if (mapPosition.Y > 0)
            mapPosition.Y = 0;
        else if (mapPosition.Y < DisplayRectangle.Height - mapSize.Height)
            mapPosition.Y =  DisplayRectangle.Height - mapSize.Height;

        Invalidate(); // Force Repaint
    }

    protected override void OnMouseLeave(EventArgs e)
    {
        // base.OnMouseLeave(e);

        dragging = false;
        // TO DO: Correct this
    }

    protected override void OnMouseUp(MouseEventArgs e)
    {
        //base.OnMouseUp(e);

        dragging = false;
    }
}
}