C#。在windows窗体上显示和移动图标
我需要在windows窗体上显示一组图标,并在运行时移动它们。我使用PictureBox控件来显示图标,但我必须要么不将PictureBox.SizeMode更改为“拉伸”,这会导致非常小的图标,要么在运行时它们看起来模糊而可怕,即使它们是高质量的图标 虽然很多人都有同样的问题,但我一直在谷歌上搜索解决方案,但毫无结果。你有解决办法吗 如果没有,您将如何在windows窗体上显示图标,以便在运行时轻松移动图标 谢谢分享你的时间和知识 编辑 下面是一些屏幕截图:上面的是设计时的PictureBox,下面是运行时的PictureBoxC#。在windows窗体上显示和移动图标,c#,winforms,transparency,icons,picturebox,C#,Winforms,Transparency,Icons,Picturebox,我需要在windows窗体上显示一组图标,并在运行时移动它们。我使用PictureBox控件来显示图标,但我必须要么不将PictureBox.SizeMode更改为“拉伸”,这会导致非常小的图标,要么在运行时它们看起来模糊而可怕,即使它们是高质量的图标 虽然很多人都有同样的问题,但我一直在谷歌上搜索解决方案,但毫无结果。你有解决办法吗 如果没有,您将如何在windows窗体上显示图标,以便在运行时轻松移动图标 谢谢分享你的时间和知识 编辑 下面是一些屏幕截图:上面的是设计时的PictureBox
覆盖
OnPaint()
并在需要的地方用e.Graphics.DrawImageUnscaled()绘制图标。覆盖OnPaint()
并在需要的地方用e.Graphics.DrawImageUnscaled()绘制图标。我使用一组32x32.png图标来完成此操作。我使用FlowLayoutPanel作为容器,并向其中添加PictureBox控件。在这个代码段中,uxIconPanel是一个FlowLayoutPanel
foreach (Image img in GetImageListForClassification(entityClass))
{
PictureBox box = new PictureBox();
box.Image = img;
box.Size = box.PreferredSize;
box.Anchor = AnchorStyles.Top | AnchorStyles.Left;
uxIconPanel.Controls.Add(box);
}
我使用一组32x32.png图标来实现这一点。我使用FlowLayoutPanel作为容器,并向其中添加PictureBox控件。在这个代码段中,uxIconPanel是一个FlowLayoutPanel
foreach (Image img in GetImageListForClassification(entityClass))
{
PictureBox box = new PictureBox();
box.Image = img;
box.Size = box.PreferredSize;
box.Anchor = AnchorStyles.Top | AnchorStyles.Left;
uxIconPanel.Controls.Add(box);
}
从一个数组开始,保存需要的图像类
- image
- left
- top
- height
- width
重写OnPaint()并在阵列中的每个图像的位置绘制
处理MouseDown事件
- track the mouse down location
- determine whether the location hits one of the images
and track which one was hit
- track the original location of the hit image
处理MouseMove事件
- if not mouse button pressed then return
- if not tracking a hit from mouse down then return
- determine the change in position of the mouse from
what it was in the mouse down event
- apply the change in position to the original image position
to set the new position of the tracked image
- Invalidate() to cause a repaint in the new position
此伪代码将提供基本的对象拖动功能。从一个数组开始,以保存需要的图像类
- image
- left
- top
- height
- width
重写OnPaint()并在阵列中的每个图像的位置绘制
处理MouseDown事件
- track the mouse down location
- determine whether the location hits one of the images
and track which one was hit
- track the original location of the hit image
处理MouseMove事件
- if not mouse button pressed then return
- if not tracking a hit from mouse down then return
- determine the change in position of the mouse from
what it was in the mouse down event
- apply the change in position to the original image position
to set the new position of the tracked image
- Invalidate() to cause a repaint in the new position
这个伪代码将提供基本的对象拖动功能。我将使用位图而不是图标,正如其他人所说。我会这样做: 首先,创建一个保存位图的类和一个委托,该委托将指向一个方法,该方法将获取位图的位置作为时间的函数
delegate Point PositionFunction(int time);
class MovingBitmap
{
private Bitmap bitmap;
private PositionFunction positionFunction;
public MovingBitmap(Bitmap bitmap, PositionFunction positionFunction)
{
if (bitmap == null)
{
throw new ArgumentNullException("bitmap");
}
else if (positionFunction == null)
{
throw new ArgumentNullException("bitmap");
}
this.bitmap = bitmap;
this.positionFunction = positionFunction;
}
public Bitmap Bitmap
{
get { return this.bitmap; }
}
public PositionFunction PositionFunction
{
get { return this.positionFunction; }
}
}
对于position函数,您需要决定位图的移动方式。(注意:时间以毫秒表示。)它可以简单到:
private Point SimpleTimeFunction(int time)
{
return new Point(time / 5, time / 5);
}
private Point ParabolaFunction(int time)
{
return new Point(time / 5, (time / 5) * (time / 5));
}
或者它可以是由多个方程组成的分段函数,例如:
if (time < 5000)
{
return new Point(time / 5, 2 * (time / 5));
}
else
{
return new Point(time / 5, time / 5) * time);
}
要实现动画效果,需要一个计时器。计时器过期时,刷新缓冲区,然后刷新控件
private System.Timers.Timer timer;
private ParameterlessVoid refreshMethod;
private delegate void ParameterlessVoid();
// Add these four lines to the constructor
this.timer = new System.Timers.Timer(1000 / 20); // 20 times per second
this.timer.AutoReset = true;
this.timer.Elapsed += this.HandleTimerElapsed;
this.refreshMethod = new ParameterlessVoid(this.Refresh);
private void HandleTimerElapsed(object sender, EventArgs e)
{
this.RefreshBuffer();
this.Invoke(this.refreshMethod);
}
private void Start()
{
this.startTime = System.Environment.TickCount;
this.timer.Start();
}
我想这基本上就是你需要做的。它还没有经过充分的测试和调试,但它应该为您指明正确的方向。我会使用位图,而不是像其他人所说的那样使用图标。我会这样做: 首先,创建一个保存位图的类和一个委托,该委托将指向一个方法,该方法将获取位图的位置作为时间的函数
delegate Point PositionFunction(int time);
class MovingBitmap
{
private Bitmap bitmap;
private PositionFunction positionFunction;
public MovingBitmap(Bitmap bitmap, PositionFunction positionFunction)
{
if (bitmap == null)
{
throw new ArgumentNullException("bitmap");
}
else if (positionFunction == null)
{
throw new ArgumentNullException("bitmap");
}
this.bitmap = bitmap;
this.positionFunction = positionFunction;
}
public Bitmap Bitmap
{
get { return this.bitmap; }
}
public PositionFunction PositionFunction
{
get { return this.positionFunction; }
}
}
对于position函数,您需要决定位图的移动方式。(注意:时间以毫秒表示。)它可以简单到:
private Point SimpleTimeFunction(int time)
{
return new Point(time / 5, time / 5);
}
private Point ParabolaFunction(int time)
{
return new Point(time / 5, (time / 5) * (time / 5));
}
或者它可以是由多个方程组成的分段函数,例如:
if (time < 5000)
{
return new Point(time / 5, 2 * (time / 5));
}
else
{
return new Point(time / 5, time / 5) * time);
}
要实现动画效果,需要一个计时器。计时器过期时,刷新缓冲区,然后刷新控件
private System.Timers.Timer timer;
private ParameterlessVoid refreshMethod;
private delegate void ParameterlessVoid();
// Add these four lines to the constructor
this.timer = new System.Timers.Timer(1000 / 20); // 20 times per second
this.timer.AutoReset = true;
this.timer.Elapsed += this.HandleTimerElapsed;
this.refreshMethod = new ParameterlessVoid(this.Refresh);
private void HandleTimerElapsed(object sender, EventArgs e)
{
this.RefreshBuffer();
this.Invoke(this.refreshMethod);
}
private void Start()
{
this.startTime = System.Environment.TickCount;
this.timer.Start();
}
我想这基本上就是你需要做的。它没有经过充分的测试和调试,但它应该为您指明正确的方向。是否被用户或代码移动了?图标的格式是什么?以编程方式。图标是512x512。您是否正在WinForms应用程序中创建“抓住猴子”广告横幅?如果是这样,请给我的结果,最好的广告有史以来。移动周围的用户或代码?图标的格式是什么?以编程方式。图标是512x512。您是否正在WinForms应用程序中创建“抓住猴子”广告横幅?如果是这样,请给我的结果,有史以来最好的广告。同样的问题。图标太小了。如果我将box.SizeMode更改为拉伸图标,看起来会很糟糕。同样的问题。图标太小了。如果我将box.SizeMode更改为拉伸图标,看起来会很糟糕。我该如何移动它们?在不同的位置绘制它们?你可以通过定时器触发表单失效。我如何移动它们?在不同的位置绘制它们?您可以通过计时器触发表单失效。