当我移动它时,如何防止pictureBox图像拖尾?

时间:2012-08-25 22:42:56

标签: c# winforms controls picturebox doublebuffered

Hello stackoverflow社区。我已经尝试过寻找类似的问题,但我只发现了有关闪烁的问题,这与我遇到的问题不一样。

每当我在面板上移动PictureBox时,我都需要帮助阻止PictureBox es跟踪。我正在制作的应用程序类似于MS Paint。当我点击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); } } 时,我可以点击并拖动它:

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));
        }
    }
}

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

PictureBox

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

奇怪的是,这只发生在Paint事件上。如果我要将面板的背景图像设为某种东西,那么移动Image将不会跟踪。只有当我在面板上绘制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)); } }} 时才会发生这种情况。

以下是enter image description here

的示例

非常感谢任何帮助,谢谢。

我简化了代码,因此更容易理解。(尾随效果仍然存在)

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();

        }


    }

}

它使用这个doubleBuffered面板类

PictureBox

现在,我的代码需要3 DoubleBuffered和1 Panel1.size = (2000, 1200);小组。

表单已最大化,PictureBox和每个size = (700, 700) PictureBox并将每个pictureBox1背景图片设置为随机的大型详细图片。当我移动{{1}}并且每次都可以重现这个时,会发生尾随效果。

2 个答案:

答案 0 :(得分:0)

您是否尝试过从OnPaint处理程序调用基础的OnPaint,或者从MouseMove中选择性地执行Invalidate / Refresh?

答案 1 :(得分:0)

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

  1. 在表单PictureBox事件
  2. 期间实例化Load
  3. PictureBox活动期间重新定位Location及其MouseMove媒体资源
  4. 重定位后PictureBox无效
  5. 在通过Paint
  6. 触发的Invalidate()事件期间重绘
  7. 我为Region设置了自定义形状(PictureBox),该形状是在VisibleChange活动期间设置的。*
  8. 如果按下鼠标左键,PictureBox仅可见(Visible == true),且图片足够大。*

    * =可选

  9. 以下是我的代码的修改摘录。我希望它们具有足够的相关性。

    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;
        }
    }