2014-01-05 40 views
1

我試圖建立自己的極座標圖。我用一個函數來畫點如下:c#同時畫很多圈

private void drawPoints() 
{ 
    this.SuspendLayout(); 
    Graphics g = this.CreateGraphics(); 

    int i = 0; 
    foreach (Point Pointaktuell in PointList) 
    { 
     int radius = 15; 

     Brush b = new SolidBrush(Color.Red); 

     g.FillEllipse(b, (int)(Pointaktuell.X - radius/2.0), (int)(Pointaktuell.Y - radius/2.0), radius, radius); 
     i++; 
    } 
    PointList.Clear(); 
    this.ResumeLayout(); 
} 

的問題是是畫一個一個之後,並且需要大量的時間。我怎樣才能一次繪製它們?

+1

首先要注意:刪除「刷B =新SolidBrush(Color.Red);」和「int radius = 15;」在foreach循環中並在循環外創建它們。 – Odrai

+0

您在每個循環步驟中實例化一個新的「SolidBrush」實例。而且你每次都重複定義「半徑」。爲什麼不把它們從循環中拿出來呢? 'const int radius = 15;'和'刷新b =新的SolidBrush(Color.Red)'爲什麼如果你需要一個計數器'i'使用'foreach'?爲什麼不''爲' –

+2

當你繪製成千上萬的圓圈時,它將會明顯變慢。不可避免地,你會重疊點,使它們消失。所以你在浪費時間繪製用戶永遠看不到的點。另一個重要的問題是你使用CreateGraphics()。這總是錯誤的,你必須使用Paint事件。它支持雙緩衝,使得這些點逐一繪製的情況變得不那麼明顯。雙位緩衝自己的位圖,所以你不必重複這樣做是另一種標準技巧,現在它是一個非常便宜的DrawImage()調用。或者使用圖表控件。 –

回答

2

優化的繪圖程序,儘量把更多的代碼放在以外的地方這個循環。不要忘記關閉IDisposable

private void drawPoints() 
{ 
    SuspendLayout(); 

    try 
    { 
     using (Graphics g = CreateGraphics()) 
     { 
      int i = 0; 
      int radius = 15; 

      using (b = new SolidBrush(Color.Red)) 
      { 
       foreach (Point Pointaktuell in PointList) 
       { 
        g.FillEllipse(b, (int)(Pointaktuell.X - radius/2.0), (int)(Pointaktuell.Y - radius/2.0), radius, radius); 
        i += 1; 
       } 
      } 
     } 
    } 
    finally { ResumeLayout(); } 
} 
+0

爲什麼試着抓住*優化*有問題?如果'SolidBrush'參數爲'null',我想只有'FillEllipse'方法可能會拋出'ArgumentNullException'。哪些*如果不能* –

+2

「終於」是非常便宜的(與「catch」相反);每當你獲得資源時,設置一個鎖,掛起(例如SuspendLayout)你必須釋放,重置,恢復(ResumeLayout)。 –

0

SolidBrush在每個循環步驟實例化。並且每次一次又一次地重新定義radiusDispose()例程不被稱爲實例化對象(這對於Graphics來說很重要)

您可以嘗試以下操作:

private void drawPoints() 
{ 
    this.SuspendLayout(); 

    const int radius = 15; 
    using (Graphics g = this.CreateGraphics()) 
    { 
     //if (g == null) { this.ResumeLayout(); return; } // # Uncomment this line if you want defensive checks 
     using (Brush b = new SolidBrush(Color.Red)) 
     { 
      for (int i = 0; i < PointList.Count; i++) 
      { 
       g.FillEllipse(b, (int)(PointList[i].X - radius/2.0), (int)(PointList[i].Y - radius/2.0), radius, radius); 
      } 
     } 
    } 

    PointList.Clear(); 
    this.ResumeLayout(); 
} 

這隻有在找你打算做所有的繪圖東西在drawPoints()和時調用它一次。如果您要定期致電drawPoints()或在流程的其他部分有更多的繪圖程序;我建議你保持這種全球Graphics gBrush b referances和Dispose()時,他們不再需要(在這種情況下,沒有更多的圖紙)