簡體   English   中英

在C#中的控件上繪制圖層的最佳方法是什么?

[英]What is the best way to draw layers on a control in c#?

簡化一點,我有一個自定義控件,它以每秒20幀的速度繪制LED條形圖聲級計(接收到數據)。 我當前的實現還可以,但是屏幕上有16個控件,這會在舊計算機上消耗過多的CPU ...我知道這樣會更好。

當前,我重寫onDraw()以按順序繪制以下圖層:

  1. 緩存的背景位圖不變
  2. 使用e.Graphics.DrawImageUnscaled()在可變位置的箭頭
  3. e.Graphics.FillRectangle()根據數據填充綠色/黃色/紅色
  4. e.Graphics.DrawString()在頂部繪制值

這是最終產品的模型:

條形圖示例

這是最好的方法嗎? 我可以想像地將所有內容預先渲染到位圖中,然后根據需要進行裁剪...並且可能仍然使用DrawString作為number(?)...,但是最好的方法是什么? 我什至應該在onDraw()中這樣做嗎? C#中的圖形功能不是我最擅長的領域。

感謝您提供的任何建議。

編輯:聽起來好像我做的和WinForms一樣好,而且實際上做得很好。 在我的開發機器上,僅需0.32毫秒即可繪制控件。 我對CPU使用率達到100%和幀丟失的投訴做出了反應,但是客戶使用的是10年以前的硬件,我懷疑圖形適配器不是很好。

盡管如此,這篇文章對於總體改進還是很有幫助的,並且確實節省了我的繪畫時間幾​​微秒:

https://stackoverflow.com/a/11025428/1195740

假設您的項目是WPF代碼。 我認為每秒20次更新比一個人可以觀看的更多,尤其是在更新次數最多的情況下。 我認為每秒進行幾次更新就足夠了,但是我當然不知道您的應用程序的要求。

我整理了一個示例,以查看WPF UserControl的性能如何,並且在不使用圖形類的情況下,perf看起來還不錯,而僅從EllipseTextBoxSlider構建TextBox 重新設置滑塊的樣式並不難,我在示例中也沒有這樣做。

設計模式

設計模式

跑步時

跑步時

源代碼

您可以在LightBar的 GitHub上找到我的項目

結論

如果有幫助,那就太好了。 您要求Advice ,這是否是最好的方法。 不知道我的示例代碼是否是最好的,而是解決此類問題的眾多方法之一。

快樂編碼,Kory

假設使用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);
    }
}

暫無
暫無

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

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