首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何防止pictureBox图像在移动时被拖曳?

如何防止pictureBox图像在移动时被拖曳?
EN

Stack Overflow用户
提问于 2012-08-26 06:42:56
回答 2查看 2.1K关注 0票数 1

你好stackoverflow社区。我已经尝试寻找类似的问题,但我只找到关于闪烁的问题,这与我遇到的问题不同。

当我在面板上移动PictureBoxes时,我需要帮助防止它们被拖到后面。我正在制作的应用程序类似于MS Paint。当我单击PictureBox时,我可以使用以下命令单击并拖动它:

代码语言:javascript
复制
private void pictureBox1_MouseDown(object sender, MouseEventArgs e)
{            
    x = e.X;
    y = e.Y;
}

private void pictureBox1_MouseMove(object sender, MouseEventArgs e)
{
    if (e.Button == MouseButtons.Left)
    {
        pictureBox1.Left += (e.X - x);
        pictureBox1.Top += (e.Y - y);
    }
}

和其他我没有点击的pictureBoxes被绘制到DoubleBuffered面板上,使用:

代码语言:javascript
复制
private void panel1_Paint(object sender, PaintEventArgs e)
{
    foreach (PictureBox pb in pboxes)
    {
        if (!pb.Visible)
        {
            e.Graphics.DrawImage(pb.BackgroundImage, new Rectangle(pb.Location, pb.Size));
        }
    }
}

由于某些原因,当我拖动PictureBox时,它的背景图像会在绘制的面板上拖动。

奇怪的是,这只发生在Paint事件上。如果我让面板的背景图像有一些东西,移动的PictureBox将不会跟踪。只有当我在面板上绘制Images时才会发生这种情况。

下面是一个例子

如果有任何帮助,我将不胜感激,谢谢。

我简化了代码以便更容易理解(仍然会产生拖尾效应)。

代码语言:javascript
复制
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Collections;

namespace WindowsFormsApplication1

{

public partial class Form1 : Form
{

    int x;
    int y;

    public Form1()
    {
        InitializeComponent();
        pictureBox1.Show();
        pictureBox2.Hide();
        pictureBox3.Hide();
    }

    private void pictureBox1_MouseDown(object sender, MouseEventArgs e)
    {            
        x = e.X;
        y = e.Y;
        panel1.Invalidate();
    }

    private void pictureBox1_MouseMove(object sender, MouseEventArgs e)
    {
        if (e.Button == MouseButtons.Left)
        {
            pictureBox1.Left += (e.X - x);
            pictureBox1.Top += (e.Y - y);
        }
    }

    private void panel1_Paint(object sender, PaintEventArgs e)
    {
        e.Graphics.DrawImage(pictureBox2.BackgroundImage, new Rectangle(pictureBox2.Location, pictureBox2.Size));
        e.Graphics.DrawImage(pictureBox3.BackgroundImage, new Rectangle(pictureBox3.Location, pictureBox3.Size));
    }


}}

它使用这个doubleBuffered面板类

代码语言:javascript
复制
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows.Forms;

namespace WindowsFormsApplication1
{
    public class DoubleBufferPanel : Panel
    {


        public DoubleBufferPanel()
        {

            // Set the value of the double-buffering style bits to true.
            this.DoubleBuffered = true;



            this.SetStyle(ControlStyles.DoubleBuffer | ControlStyles.UserPaint |
             ControlStyles.AllPaintingInWmPaint, true);

            this.UpdateStyles();

        }


    }

}

现在我的代码需要3个PictureBox和1个DoubleBuffered面板。

表格是最大化的,Panel1.size = (2000, 1200);和each PictureBox size = (700, 700),并将每个PictureBoxes背景图像设置为随机的大细节图像。当我移动pictureBox1时,拖尾效果就会出现,我每次都可以重现这个效果。

EN

回答 2

Stack Overflow用户

发布于 2012-08-27 01:49:46

您是否尝试过从OnPaint处理程序调用基类的OnPaint,或者从MouseMove中选择性地执行无效/刷新?

票数 0
EN

Stack Overflow用户

发布于 2016-07-01 12:34:23

我知道这是几年前的事了,但今天我也遇到了类似的麻烦。我正在单击并拖动一个用于放大图像部分的PictureBox。通过获得正确的操作顺序解决了这些问题:大小、移动、绘制。我通过以下方式解决了这个问题:

  1. 在窗体的Load event

期间实例化PictureBox

  1. MouseMove event

期间使用Location属性重新定位MouseMove

  1. Invalidating

之后重新定位PictureBox

通过Invalidate()触发的事件期间的

  1. 重绘

  1. 我为我的PictureBox设置了一个自定义形状(Region),它是在VisibleChange事件期间设置的。*

仅当按下鼠标左键且图像足够大时,

  1. PictureBox才可见(Visible == true)。*

*=可选的

以下是我的代码中经过修改的摘录。我希望它们足够相关。

代码语言:javascript
复制
public Form1()
{
    InitializeComponent();

    this.Paint += new System.Windows.Forms.PaintEventHandler(Form1_Paint);
    Main_PictureBox.Paint += new PaintEventHandler(Main_PictureBox_Paint);
    Main_PictureBox.MouseDown += new MouseEventHandler(StartZoom);
    Zoom_PictureBox.MouseDown += new MouseEventHandler(StartZoom);
    Main_PictureBox.MouseMove += new MouseEventHandler(MoveZoom);
    Main_PictureBox.MouseUp += new MouseEventHandler(EndZoom);
    Main_PictureBox.MouseLeave += new EventHandler(EndZoom);
    Zoom_PictureBox.MouseUp += new MouseEventHandler(EndZoom);
    Zoom_PictureBox.VisibleChanged += new EventHandler(Zoom_PictureBox_VisibleRegion);
    Zoom_PictureBox.Paint += new PaintEventHandler(Zoom_PictureBox_Paint);
}
private void Form1_Paint(object sender, PaintEventArgs e)
{
    int H = flowLayoutPanel1.Height - flowLayoutPanel1.Margin.Size.Height;
    Main_PictureBox.MinimumSize = new Size(0, 0);
    Main_PictureBox.MaximumSize = new Size(flowLayoutPanel1.Width, H);
}
private void Main_PictureBox_Paint(object sender, PaintEventArgs e)
{
    Main_PictureBox.Parent.MaximumSize = Main_PictureBox.Size + Main_PictureBox.Margin.Size;
}
private void DisplayImage(object sender, EventArgs e)
{
    Image img = ((PictureBox)sender).Image;

    int W = img.Width;
    int H = img.Height;
    float ratio = (float)W / (float)H;

    Main_PictureBox.Image = img;
    Main_PictureBox.Size = new Size(W, H);
    float TestRatio = ((float)Main_PictureBox.Width / (float)Main_PictureBox.Height);
    if (TestRatio < ratio)
        Main_PictureBox.Height = (int)((float)Main_PictureBox.Width / ratio);
    else if (TestRatio > ratio)
        Main_PictureBox.Width = (int)((float)Main_PictureBox.Height * ratio);
}
private void Zoom_PictureBox_VisibleRegion(object sender, EventArgs e)
{
    using (var gp = new System.Drawing.Drawing2D.GraphicsPath())
    {
        gp.AddEllipse(new Rectangle(0, 0, this.Zoom_PictureBox.Width, this.Zoom_PictureBox.Height));
        this.Zoom_PictureBox.Region = new Region(gp);
    }
}
private void Zoom_PictureBox_Paint(object sender, PaintEventArgs e)
{
    e.Graphics.DrawImage(Main_PictureBox.Image, e.ClipRectangle, cropRectangle, GraphicsUnit.Pixel);
}
private void StartZoom(object sender, MouseEventArgs e)
{
    if (e.Button == MouseButtons.Left && scale > 1.25)
    {
        int dX = Zoom_PictureBox.Width / 2;
        int dY = Zoom_PictureBox.Height / 2;
        Zoom_PictureBox.Visible = true;
        Zoom_PictureBox.Location = new Point(e.X - dX, e.Y - dY);
    }
}
private void MoveZoom(object sender, MouseEventArgs e)
{
    if (Main_PictureBox.Image != null)
    {
        Zoom_PictureBox.Visible = (e.Button == MouseButtons.Left && scale > 1.25);
        if (Zoom_PictureBox.Visible && e.Button == MouseButtons.Left)
        {
            int dX = Zoom_PictureBox.Width / 2;
            int dY = Zoom_PictureBox.Height / 2;

            Zoom_PictureBox.Location = new Point(e.X - dX, e.Y - dY);
            Zoom_PictureBox.Invalidate();
        }
    }
}
private void EndZoom(object sender, MouseEventArgs e)
{
    if (e.Button == MouseButtons.Left)
        EndZoom();
}
private void EndZoom(object sender, EventArgs e)
{
    EndZoom();
}
private void EndZoom()
{
    Zoom_PictureBox.Visible = false;
}
private Rectangle cropRectangle
{
    get
    {
        if (Main_PictureBox.Image != null)
        {
            Point origin = Main_PictureBox.PointToScreen(new Point(0, 0));
            float X = (float)(MousePosition.X - origin.X);
            return new Rectangle(
                (int)(scale * X) - Zoom_PictureBox.Width / 2,
                (int)(scale * (float)(MousePosition.Y - origin.Y)) - Zoom_PictureBox.Height / 2,
                Zoom_PictureBox.Width,
                Zoom_PictureBox.Height);
        }
        else
            return new Rectangle();
    }
}
private float scale
{
    get
    {
        if (Main_PictureBox.Image != null)
            return (float)Main_PictureBox.Image.Height / (float)Main_PictureBox.Height;
        else
            return 0;
    }
}
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/12126226

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档