简化一下,我有一个自定义控件,以每秒20帧的速度绘制LED条形声级计(收到数据时)。我当前的实现工作正常,但是屏幕上有16个控件,它在旧机器上消耗了太多的CPU ......我知道它可以更好。
目前我正在重写onDraw()以按顺序绘制以下图层:
这是最终产品的模型:
这是最好的方法吗?我可以想象将所有内容预渲染成位图并根据需要剪切它们......并且可能仍然使用DrawString作为数字(?)......但最好的方法是什么?我应该在onDraw()中做到这一点吗? c#中的图形函数不是我最强的区域。
感谢您提供任何建议。
编辑:听起来我的表现和WinForms一样好,而且它实际上做得很好。在我的开发机器上,它只用了0.32ms来绘制控件。我对100%CPU使用率和丢帧率的投诉作出反应,但客户使用的是10年前的硬件,我怀疑图形适配器不是很好。
尽管如此,这篇文章对于一般的改进非常有帮助,并且在绘画时间上缩短了几微秒:
答案 0 :(得分:0)
假设您的项目是WPF代码。我认为每秒20次更新比一个人可以观看的更多,尤其是顶级数字更新。我认为一秒钟的更新就足够了,但我当然不知道你的应用程序的要求。
我掀起了一个示例,看看WPF UserControl可能会如何执行,并且在不使用图形类的情况下表现良好,只需从Ellipse
,TextBox
和{{1}构建控件}。滑块不难重新设计,我在样本中没有这样做。
您可以在LightBar
在GitHub上找到我的项目如果这有帮助,那很好。您要求Slider
以及这是否是最好的方法。不确定我的示例代码是否是最好的,而是可以解决任何此类问题的众多方法之一。
快乐的编码,Kory
答案 1 :(得分:0)
假设Winforms,这是一个相当快速且相当肮脏的例子。
它使用两个固定图像:
它不显示黄色三角形或数字。
它甚至不会以持久的方式绘制图形。但对于这种情况,这可能是不必要的..!?
因此它留有一些改进空间。但它确实有效,而且非常简单:
public Form1()
{
InitializeComponent();
Bitmap level = (Bitmap)Image.FromFile("D:\\LEDmeter0.png");
bmpL0 = level.Clone(new Rectangle(Point.Empty, level.Size),
PixelFormat.Format32bppPArgb);
level = (Bitmap)Image.FromFile("D:\\LEDmeter1.png");
bmpL1 = level.Clone(new Rectangle(Point.Empty, level.Size),
PixelFormat.Format32bppPArgb);
}
Bitmap bmpL0 = null;
Bitmap bmpL1 = null;
Random R = new Random(0);
private void timer1_Tick(object sender, EventArgs e)
{
Size sz = pictureBox2.ClientSize;
int level = R.Next(10) + R.Next(5) + R.Next(3) ; // 0-17
level = 27 * level + 50;
using (Graphics G = pictureBox2.CreateGraphics())
{
G.DrawImage(bmpL1, new Rectangle(0, 0, sz.Width, sz.Height),
new Rectangle(0, 0, sz.Width, sz.Height), GraphicsUnit.Pixel);
G.DrawImage(bmpL0, new Rectangle(0, 0, sz.Width, level),
new Rectangle(0, 0, sz.Width, level), GraphicsUnit.Pixel);
}
}