鼠标 在 picturebox 上拖动图片的问题

bolv6666 2008-04-15 07:46:57
现在已经实现了鼠标在picturebox上点住然后拖动图片,但是效果不好:


private void pictureBox1_MouseMove(object sender, MouseEventArgs e)
{
if (WhetherSelected)
{
DriftX = e.X - p.X;
DriftY = e.Y - p.Y;
mx += DriftX;
my += DriftY;

Graphics gg = pictureBox1.CreateGraphics();
gg.Clear(pictureBox1.BackColor);//这句如果不加的话,就会产生拖影
gg.DrawImage(this.pictureBox1.Image, mx, my);
p.X = e.X;
p.Y = e.Y;
gg.Dispose();
}
}

主要是通过gg.DrawImage(this.pictureBox1.Image, mx, my);来重绘图片的,虽然基本功能实现,但是由两个问题:
1:鼠标拖动时会不停的闪烁刷新,这是由于gg.Clear(pictureBox1.BackColor),但不加这句就有拖影产生
2:用gg.DrawImage产生新图的最大问题就是 当你最小化或其他什么东西经过它上面时就被擦除了

请问各位有没有两全其美的实现方法。我个人觉得:如果能够知道怎么在picturebox中定位图片位置就好了,这样也不用gg.DrawImage了,请各位指点指点,多谢
...全文
611 14 打赏 收藏 转发到动态 举报
写回复
用AI写文章
14 条回复
切换为时间正序
请发表友善的回复…
发表回复
c1000095815 2011-11-14
  • 打赏
  • 举报
回复
我也搞了一个。。bool wselected = false;
Point p = new Point();
private void pictureBox1_MouseDown(object sender, MouseEventArgs e)
{
pictureBox1.Cursor = Cursors.Hand; //按下鼠标时,将鼠标形状改为手型
wselected = true;
p.X = e.X;
p.Y = e.Y;
}
int driftX = 0, driftY = 0;
int mx = 0, my = 0;
private void pictureBox1_MouseMove(object sender, MouseEventArgs e)
{
if (wselected)
{
driftX = p.X - e.X;
driftY = p.Y - e.Y;

mx = mx - driftX;
my = my - driftY;

Bitmap JPEG = new Bitmap(this.pictureBox1.Image);

Graphics g = pictureBox1.CreateGraphics();
g.Clear(pictureBox1.BackColor);
g.DrawImage(JPEG, mx, my);

p.X = e.X;
p.Y = e.Y;

JPEG.Dispose();
g.Dispose();//图像移动的距离
}
}

private void pictureBox1_MouseUp(object sender, MouseEventArgs e)
{
pictureBox1.Cursor = Cursors.Default; //松开鼠标时,形状恢复为箭头

wselected = false ;
this.pictureBox1.Cursor = Cursors.Default;
}
c1000095815 2011-11-14
  • 打赏
  • 举报
回复
谢了~
wzuomin 2008-04-16
  • 打赏
  • 举报
回复
我上面的那部分自动转换的C#代码好像有问题,改了一下重新贴出来了

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;

namespace WindowsApplication1
{
public partial class Form1 : Form
{
Point offset = new Point(0, 0);
Point p;
Bitmap srcBitmap;
Panel Panel1;

public Form1()
{
InitializeComponent();
}

private void Panel1_MouseDown(object sender, System.Windows.Forms.MouseEventArgs e)
{
p = e.Location;
Panel1.Cursor = Cursors.Hand;
}

private void Panel1_MouseMove(object sender, System.Windows.Forms.MouseEventArgs e)
{
if (e.Button == MouseButtons.Left)
{
offset.Offset(e.X - p.X, e.Y - p.Y);
this.MyReDrawTest(offset.X, offset.Y);
p = e.Location;
}
}

private void Panel1_MouseUp(object sender, System.Windows.Forms.MouseEventArgs e)
{
Panel1.Cursor = Cursors.Default;
}

private void Panel1_Paint(object sender, System.Windows.Forms.PaintEventArgs e)
{
this.MyReDrawTest(offset.X, offset.Y);
}

private void MyReDrawTest(int x, int y)
{
if (srcBitmap == null)
return;
BufferedGraphicsContext currentContext = BufferedGraphicsManager.Current;
BufferedGraphics myBuffer = currentContext.Allocate(this.Panel1.CreateGraphics(), this.Panel1.DisplayRectangle);

myBuffer.Graphics.Clear(this.Panel1.BackColor);
myBuffer.Graphics.DrawImage(srcBitmap, offset);
myBuffer.Render( this.Panel1 .CreateGraphics() );
myBuffer.Dispose();
}

private void Form1_Load(object sender, System.EventArgs e)
{
Panel1 = new Panel();
Panel1.Dock = DockStyle.Fill;
Panel1.MouseDown += Panel1_MouseDown;
Panel1.MouseMove += Panel1_MouseMove;
Panel1.MouseUp += Panel1_MouseUp;
Panel1.Paint += Panel1_Paint;
this.Controls.Add(Panel1);

OpenFileDialog cd = new OpenFileDialog();
cd.Filter = "bmp文件 (*.bmp)|*.bmp|jpg文件 (*.jpg)|*.jpg|gif文件 (*.gif)|*.gif|所有文件|*.*";
if (cd.ShowDialog() == DialogResult.OK)
{
srcBitmap = new Bitmap(cd.FileName);
offset = new Point(0, 0);
Panel1.Invalidate();
}
}
}
}
wzuomin 2008-04-16
  • 打赏
  • 举报
回复
来一个我写的最好用的,嘿嘿


Public Class Form1

Dim offset As New Point(0, 0)
Dim p As Point
Dim srcBitmap As Bitmap
Dim WithEvents Panel1 As Panel

Private Sub Panel1_MouseDown(ByVal sender As Object, ByVal e As System.Windows.Forms.MouseEventArgs) Handles Panel1.MouseDown
p = e.Location
Panel1.Cursor = Cursors.Hand
End Sub

Private Sub Panel1_MouseMove(ByVal sender As Object, ByVal e As System.Windows.Forms.MouseEventArgs) Handles Panel1.MouseMove
If e.Button = Windows.Forms.MouseButtons.Left Then
offset.Offset(e.X - p.X, e.Y - p.Y)
Call Me.MyReDrawTest(offset.X, offset.Y)
p = e.Location
End If
End Sub

Private Sub Panel1_MouseUp(ByVal sender As Object, ByVal e As System.Windows.Forms.MouseEventArgs) Handles Panel1.MouseUp
Panel1.Cursor = Cursors.Default
End Sub

Private Sub Panel1_Paint(ByVal sender As Object, ByVal e As System.Windows.Forms.PaintEventArgs) Handles Panel1.Paint
Call Me.MyReDrawTest(offset.X, offset.Y)
End Sub

Private Sub MyReDrawTest(ByVal x As Integer, ByVal y As Integer)
If srcBitmap Is Nothing Then Exit Sub

Dim currentContext As BufferedGraphicsContext = BufferedGraphicsManager.Current
Dim myBuffer As BufferedGraphics = currentContext.Allocate(Me.Panel1.CreateGraphics, Me.Panel1.DisplayRectangle)

myBuffer.Graphics.Clear(Me.Panel1.BackColor)
myBuffer.Graphics.DrawImage(srcBitmap, offset)
myBuffer.Render(Me.Panel1.CreateGraphics)
myBuffer.Dispose()
End Sub

Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
Panel1 = New Panel
Panel1.Dock = DockStyle.Fill
Me.Controls.Add(Panel1)
Dim cd As New OpenFileDialog
cd.Filter = "bmp文件 (*.bmp)|*.bmp|jpg文件 (*.jpg)|*.jpg|gif文件 (*.gif)|*.gif|所有文件|*.*"
If cd.ShowDialog = Windows.Forms.DialogResult.OK Then
srcBitmap = New Bitmap(cd.FileName)
offset = New Point(0, 0)
Panel1.Invalidate()
End If
End Sub
End Class



public class Form1
{

Point offset = new Point(0, 0);
Point p;
Bitmap srcBitmap;
Panel Panel1;

private void Panel1_MouseDown(object sender, System.Windows.Forms.MouseEventArgs e)
{
p = e.Location;
Panel1.Cursor = Cursors.Hand;
}

private void Panel1_MouseMove(object sender, System.Windows.Forms.MouseEventArgs e)
{
if (e.Button == Windows.Forms.MouseButtons.Left) {
offset.Offset(e.X - p.X, e.Y - p.Y);
this.MyReDrawTest(offset.X, offset.Y);
p = e.Location;
}
}

private void Panel1_MouseUp(object sender, System.Windows.Forms.MouseEventArgs e)
{
Panel1.Cursor = Cursors.Default;
}

private void Panel1_Paint(object sender, System.Windows.Forms.PaintEventArgs e)
{
this.MyReDrawTest(offset.X, offset.Y);
}

private void MyReDrawTest(int x, int y)
{
if (srcBitmap == null)
return; // TODO: might not be correct. Was : Exit Sub


BufferedGraphicsContext currentContext = BufferedGraphicsManager.Current;
BufferedGraphics myBuffer = currentContext.Allocate(this.Panel1.CreateGraphics, this.Panel1.DisplayRectangle);

myBuffer.Graphics.Clear(this.Panel1.BackColor);
myBuffer.Graphics.DrawImage(srcBitmap, offset);
myBuffer.Render(this.Panel1.CreateGraphics);
myBuffer.Dispose();
}

private void Form1_Load(object sender, System.EventArgs e)
{
Panel1 = new Panel();
Panel1.Dock = DockStyle.Fill;
this.Controls.Add(Panel1);
OpenFileDialog cd = new OpenFileDialog();
cd.Filter = "bmp文件 (*.bmp)|*.bmp|jpg文件 (*.jpg)|*.jpg|gif文件 (*.gif)|*.gif|所有文件|*.*";
if (cd.ShowDialog == Windows.Forms.DialogResult.OK) {
srcBitmap = new Bitmap(cd.FileName);
offset = new Point(0, 0);
Panel1.Invalidate();
}
}
}
cxfcxf8 2008-04-16
  • 打赏
  • 举报
回复
http://www.codeproject.com/KB/GDI-plus/Gradiator.aspx
来个功能强大的。
fly_to_sky 2008-04-16
  • 打赏
  • 举报
回复
<summary>
/// 设置鼠标单击的坐标,以及图片的坐标
/// </summary>
int mouseX;
int mouseY;
int picX;
int picY;

/// <summary>
/// 当鼠标单击时,给鼠标设定值。初始化。
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void pictureBox1_MouseDown(object sender, MouseEventArgs e)
{
mouseX = Cursor.Position.X;
mouseY = Cursor.Position.Y;
picX = this.pictureBox1.Left;
picY = this.pictureBox1.Top;

//if (isMouseMoveEventAviable == false)
// //添加鼠标移动事件
// this.movablePic.MouseMove += this.movablePic_MouseMove;
}

/// <summary>
/// 根据鼠标的移动的值,设置
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void pictureBox1_MouseMove(object sender, MouseEventArgs e)
{
int y = Cursor.Position.Y - mouseY + picY;
int x = Cursor.Position.X - mouseX + picX;
if (e.Button == MouseButtons.Left)
{
this.pictureBox1.Top = y;
this.pictureBox1.Left = x;
}
}

private void pictureBox1_MouseUp(object sender, MouseEventArgs e)
{
if (this.pictureBox1.Left > this.Width || (this.pictureBox1.Left + pictureBox1.Width < 0))
{
this.pictureBox1.Left = picX;
this.pictureBox1.Top = picY;
}
if (this.pictureBox1.Top > this.Height || this.pictureBox1.Top + pictureBox1.Height < 0)
{
this.pictureBox1.Left = picX;
this.pictureBox1.Top = picY;
}
mouseX = 0;
mouseY = 0;

}
private void Form1_Load(object sender, EventArgs e)
{
this.pictureBox1.Cursor = Cursors.SizeAll;
}
ojekleen 2008-04-16
  • 打赏
  • 举报
回复
标记
光义 2008-04-16
  • 打赏
  • 举报
回复
/// <summary>
/// 设置鼠标单击的坐标,以及图片的坐标
/// </summary>
int mouseX;
int mouseY;
int picX;
int picY;

/// <summary>
/// 当鼠标单击时,给鼠标设定值。初始化。
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void pictureBox1_MouseDown(object sender, MouseEventArgs e)
{
mouseX = Cursor.Position.X;
mouseY = Cursor.Position.Y;
picX = this.pictureBox1.Left;
picY = this.pictureBox1.Top;

//if (isMouseMoveEventAviable == false)
// //添加鼠标移动事件
// this.movablePic.MouseMove += this.movablePic_MouseMove;
}

/// <summary>
/// 根据鼠标的移动的值,设置
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void pictureBox1_MouseMove(object sender, MouseEventArgs e)
{
int y = Cursor.Position.Y - mouseY + picY;
int x = Cursor.Position.X - mouseX + picX;
if (e.Button == MouseButtons.Left)
{
this.pictureBox1.Top = y;
this.pictureBox1.Left = x;
}
}

private void pictureBox1_MouseUp(object sender, MouseEventArgs e)
{
mouseX = 0;
mouseY = 0;
if (this.pictureBox1.Location.X < 0 )
{
this.pictureBox1.Left = 0;

}
if ( this.pictureBox1.Location.Y < 0)
{
this.pictureBox1.Top = 0;
}
if ((this.pictureBox1.Left + this.pictureBox1.Width) > this.ClientSize.Width )
{
this.pictureBox1.Left = this.ClientSize.Width - this.pictureBox1.Width;
}
if ((this.pictureBox1.Top + this.pictureBox1.Height) > this.ClientSize.Height)
{
this.pictureBox1.Top = this.ClientSize.Height - this.pictureBox1.Height;
}
}

private void Form1_Click(object sender, EventArgs e)
{
this.pictureBox1.Cursor = Cursors.SizeAll;
}
光义 2008-04-16
  • 打赏
  • 举报
回复
试试
bolv6666 2008-04-16
  • 打赏
  • 举报
回复
还是不行,基本效果都显示不了了,哪里出了问题?
春天的气息 2008-04-15
  • 打赏
  • 举报
回复
顶!
另外用java script效果也不错的!
jinjazz 2008-04-15
  • 打赏
  • 举报
回复
改良了一下
http://blog.csdn.net/jinjazz/archive/2008/04/15/2295229.aspx
jinjazz 2008-04-15
  • 打赏
  • 举报
回复
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using System.Data.SqlClient;
namespace WindowsApplication2
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();

}

bool bPictureBoxDragging = false;
Point oPointClicked;

private void pictureBox1_MouseDown(object sender, MouseEventArgs e)
{

bPictureBoxDragging = true;
oPointClicked = new Point(e.X, e.Y);


}

private void pictureBox1_MouseMove(object sender, MouseEventArgs e)
{
if (bPictureBoxDragging)
{
Point oMoveToPoint;
oMoveToPoint = this.PointToClient(pictureBox1.PointToScreen(new Point(e.X, e.Y)));
oMoveToPoint.Offset(oPointClicked.X * -1, oPointClicked.Y * -1);
pictureBox1.Location = oMoveToPoint;
}

}

private void pictureBox1_MouseUp(object sender, MouseEventArgs e)
{
bPictureBoxDragging = false;
}
}
}
dancingbit 2008-04-15
  • 打赏
  • 举报
回复
把重绘代码放在Paint事件处理方法中,需要重绘的时候自然就会重绘,比如最小化后还原,比如被遮挡住后再次显示...
如果需要控制手动的更新,来一个Invalidate()就是了,这样,还不需要Clear。

110,577

社区成员

发帖
与我相关
我的任务
社区描述
.NET技术 C#
社区管理员
  • C#
  • Web++
  • by_封爱
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告

让您成为最强悍的C#开发者

试试用AI创作助手写篇文章吧