Hello stackoverflow community. I already tried looking for a similar question but I only found questions about flickering, which isn't the same as the problem I am having.
I need help preventing the PictureBox
es from trailing whenever I move them across a panel. The application I am making is similar to MS Paint. When I click a PictureBox
I can click and drag it using:
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);
}
}
and the other pictureBoxes which I did Not click are painted to the DoubleBuffered panel, using:
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));
}
}
}
For some reason when I drag a PictureBox
it's background Image drags across the painted panel.
Weird thing is, this only happens on the Paint event. If I were to make the panel's background Image something, the moving PictureBox
won't trail. It only happens when I'm painting Image
s onto the panel.
Here is an example
I would greatly appreciate any help, thanks.
I simplified the code so it'll be easier to understand.(The trailing effect still occurs)
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));
}
}}
And it uses this doubleBuffered panel class
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();
}
}
}
Now my code calls for 3 PictureBox
, and 1 DoubleBuffered
panel.
The form is maximized, Panel1.size = (2000, 1200);
and each PictureBox
size = (700, 700)
and set each PictureBox
es background Image to a random large detailed image. The trailing effect occurs when I move pictureBox1
and I can reproduce this every time.
您是否尝试过从OnPaint处理程序调用基础的OnPaint或从MouseMove进行选择性的Invalidate / Refresh?
I know that this was years ago, but I was having similar trouble today. I was click-and-dragging a PictureBox
for magnifying an image section. The issues were solved by getting the right order of operations: size, move, paint. I solved the issue by:
PictureBox
during the form's Load
event PictureBox
with its Location
property during the MouseMove
event PictureBox
after the relocation Paint
event, which was triggered via Invalidate()
Region
) for my PictureBox
, which was set during the VisibleChange
event.* The PictureBox
was only visible ( Visible == true
) if the left mouse button was pressed, and the image was large enough.*
* = optional
Here are modified excerpts from my code. I hope that they are sufficiently relevant.
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;
}
}
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.