C#,用鼠标拖动图片的程序,拖动时图片一直闪烁。
如题所示,首先我在窗体上画了一张图片(这张图片是我电脑上已有的)。然后我想通过程序实现:鼠标按下时,图片在窗体中显示的位置随着鼠标的拖动实时变化的功能。但是运行程序后发现...
如题所示,首先我在窗体上画了一张图片(这张图片是我电脑上已有的)。然后我想通过程序实现:鼠标按下时,图片在窗体中显示的位置随着鼠标的拖动实时变化的功能。但是运行程序后发现鼠标拖动时(图片移动过程中)图片会不停的闪烁。然后我试着将图片放入PictureBox容器中,通过改变PictureBox的Location值来达到类似的目的,问题确实得到了解决。我想问的是:直接将图片放在窗体上显示时,有什么方法可以解决图片闪烁的的方法?刚开始学C#,不要讲太深奥,谢谢!(由于”百度知道“提示字数超限,故将程序截图成了图片,图片中程序分为双栏,阅读顺序与在Word中设为双栏时的阅读顺序一致,即:先从上到下阅读左边部分,再从上到下阅读右边部分。)
展开
2个回答
展开全部
鼠标up的时候,设置了mouseStatus = false。但是在paint事件中 mouseStatus 为 false时是不绘制图像的。所以如果窗口刷新的话,你的图像就会消失了。而且你使用了三对变量来记录图像与鼠标的位置,其实可以简单一点的。象下面这样
[STAThread]
public static void Main(string[] args)
{
var form = new ImageForm();
form.ShowDialog();
}
private class ImageForm : Form
{
private readonly Image image; // 需要绘制的图像
private Point imgLocation; // 图像的位置
private Point mouseLocation; // 鼠标的最后位置
private bool moveImage; // 当前是不是在移动图像操作
public ImageForm()
{
this.Size = new Size(800, 600);
/*this.DoubleBuffered = true;*/
this.SetStyle(
ControlStyles.OptimizedDoubleBuffer | ControlStyles.ResizeRedraw | ControlStyles.AllPaintingInWmPaint,
true);
this.UpdateStyles();
var imgPath = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.Desktop), "例子图片.jpg");
this.image = Image.FromFile(imgPath); // 载入图像
this.mouseLocation = Point.Empty;
this.imgLocation = Point.Empty;
}
private bool MouseOverImage()
{
// 鼠标是不是在图像上
var mouse = this.PointToClient(MousePosition);
var rectangle = new Rectangle(this.imgLocation, this.image.Size);
return rectangle.Contains(mouse);
}
protected override void OnMouseUp(MouseEventArgs e)
{
base.OnMouseUp(e);
if (e.Button == MouseButtons.Left)
{
// 停止移动图像
this.moveImage = false;
}
}
protected override void OnMouseDown(MouseEventArgs e)
{
base.OnMouseDown(e);
if (e.Button == MouseButtons.Left && this.MouseOverImage())
{
// 鼠标在图像上点左键开始移动图像
this.mouseLocation = e.Location;
this.moveImage = true;
}
}
// 双击重置图像位置
protected override void OnMouseDoubleClick(MouseEventArgs e)
{
base.OnMouseDoubleClick(e);
this.imgLocation = Point.Empty;
this.Invalidate();
}
protected override void OnMouseMove(MouseEventArgs e)
{
base.OnMouseMove(e);
if (this.moveImage)
{
// 根据鼠标移动偏移量,计算出图片的新的位置
var offset = new Point(e.Location.X - this.mouseLocation.X, e.Location.Y - this.mouseLocation.Y);
this.imgLocation.Offset(offset);
this.mouseLocation = e.Location; // 记录鼠标的最新位置
}
this.Invalidate(); // 要求重绘图像
}
protected override void OnPaint(PaintEventArgs e)
{
base.OnPaint(e);
var graphics = e.Graphics;
graphics.Clear(this.BackColor);
graphics.DrawImage(
this.image,
new Rectangle(this.imgLocation, this.image.Size),
new Rectangle(new Point(0, 0), this.image.Size),
GraphicsUnit.Pixel);
if (this.MouseOverImage())
{
// 如果鼠标在图像上,就在图像四周画个边框
using (Brush brush = new SolidBrush(Color.Black))
{
using (var pen = new Pen(brush, 3))
{
graphics.DrawRectangle(pen, new Rectangle(this.imgLocation, this.image.Size));
}
}
}
}
}
追问
非常感谢您的热心解答,你的回答也非常那好,但另有人先回答,而且回答得也很不错,所以采纳了另一人的回答。望谅解!
展开全部
建议将C#窗体有个叫双缓冲的属性设置为true试试
追问
首先,谢谢!按照你所说的确实实现了。然后,这个程序还有一点儿问题,拖动完成时,在鼠标Up的那一瞬间,有时图片会在窗体中消失(什么都没有,显示空白窗体),但是在下一次鼠标 按下并Move时,图片会在消失的位置重现了,有时又不会出现消失,显示完全正常。请问是我程序哪儿出错了吗?如果你觉得我描述得不够清楚,可以把程序输入Visual Studio中走一遍,但这样可能要麻烦你输程序了,又是”字数超限“。
追答
你可以不停的画窗体解决这个问题,可能paint的时候刚好是空的,鼠标没点上的时候就不画了。把if (mousestatu)去掉试试
本回答被提问者采纳
已赞过
已踩过<
评论
收起
你对这个回答的评价是?
推荐律师服务:
若未解决您的问题,请您详细描述您的问题,通过百度律临进行免费专业咨询