簡體   English   中英

如何防止在移動PictureBox圖像時拖尾?

[英]How do I prevent pictureBox images from trailing while I move it?

您好stackoverflow社區。 我已經嘗試尋找類似的問題,但是我只發現了有關閃爍的問題,這與我遇到的問題不同。

每當我在面板上移動它們時,我都需要幫助防止PictureBox拖尾。 我正在制作的應用程序類似於MS Paint。 單擊PictureBox ,可以使用以下方法單擊並拖動它:

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

我沒有單擊的其他pictureBox繪制到DoubleBuffered面板,使用:

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將不會移動。 僅在將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));
    }


}}

它使用了這個doubleBuffered面板類

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); 並且每個PictureBox size = (700, 700) PictureBox size = (700, 700)並將每個PictureBox ES背景圖像設置為隨機的大型詳細圖像。 當我移動pictureBox1時會出現拖尾效果,並且每次都可以重現此效果。

您是否嘗試過從OnPaint處理程序調用基礎的OnPaint或從MouseMove進行選擇性的Invalidate / Refresh?

我知道這是幾年前的事,但是今天我遇到了類似的麻煩。 我單擊並拖動PictureBox來放大圖像部分。 通過正確的操作順序解決了這些問題:大小,移動,油漆。 我通過以下方式解決了這個問題:

  1. 在窗體的Load事件期間實例化PictureBox
  2. MouseMove事件期間使用其Location屬性重新定位PictureBox
  3. 重定位后使PictureBox無效
  4. Paint事件期間重Paint ,該事件是通過Invalidate()觸發的
  5. 我為PictureBox設置了一個自定義形狀( Region ),該形狀是在VisibleChange事件中設置的。*
  6. 僅當按下鼠標左鍵並且圖像足夠大時, PictureBox才可見( Visible == true )。*

    * =可選

這是我的代碼的節選摘錄。 我希望它們足夠相關。

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

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM