2013-01-20 39 views
3

我有四個PictureBoxes(每個圖片框代表一個骰子)和一個Timer,它改變每100ms源圖片(在內存中加載爲List<Bitmap> imagesLoadedFromIncludedResources)。同時更新多個圖片框

enter image description here

代碼:

private List<PictureBox> dices = new List<PictureBox>(); 

private void timer_diceImageChanger_Tick(object sender, EventArgs e) 
{ 
    foreach (PictureBox onePictureBox in dices) 
    { 
     oneDice.WaitOnLoad = false; 
     onePictureBox.Image = //... ; 
     oneDice.Refresh(); 
    } 
} 

我需要變化所有圖像一次 - 在這一刻,你可以看到圖像從左至右不斷變化小延遲

我試過每個PictureBox(使用Control.Invoke方法從this answer)一個Thread變種 - 它在視覺上沒有什麼更好但不完美。

+0

你預緩存你正在切換的'Bitmap'對象?如果你每次從磁盤加載都會有輕微的延遲.. –

+0

是的,我預先將'Form1_Load(...)''Bitmap'緩存到'List '中,[this method](http: /stackoverflow.com/a/3567824/752142) – illagrenan

+0

你的源圖像有多大?我無法想象在屏幕截圖中顯示的內容會有明顯延遲(假設源圖像實際上很小)。 –

回答

4

您可以嘗試暫停表單的佈局邏輯:

SuspendLayout(); 
// set images to pictureboxes 
ResumeLayout(false); 
+1

'SuspendLayout()'很好,謝謝! – illagrenan

0
Parallel.ForEach 
(
    dices, 
    new ParallelOptions { MaxDegreeOfParallelism = 4 }, 
    (dice) => 
    { 
     dice.Image = ...; 
     dice.WaitOnLoad = false; 
     dice.Refresh(); 
    } 
); 

問題是UI控件只能從UI線程訪問。如果你想使用這種方法,你必須創建一個你的PictureBox的副本,然後在操作完成後替換UI的副本。

另一種方法是創建兩個PictureBox,第一個只在另一個的頂部(隱藏後者)...您更改所有圖像,然後,一旦處理完成,您將遍歷所有後面的那些將它們放在頂部,這會導致較小的延遲。

0

我會處理這個不同 - 它已經有一段時間,因爲我已經與WinForms的東西玩,但我可能會採取更多的控制權渲染圖像。

在這個例子中,我已經得到了所有圖像在垂直堆疊的一個源位圖,存儲在裝配的資源:

namespace WindowsFormsApplication1 
{ 
    public partial class Form1 : Form 
    { 
     private Timer timer; 

     private Bitmap dice; 

     private int[] currentValues = new int[6]; 

     private Random random = new Random(); 

     public Form1() 
     { 
      InitializeComponent(); 
      this.timer = new Timer(); 
      this.timer.Interval = 500; 
      this.timer.Tick += TimerOnTick; 

      this.dice = Properties.Resources.Dice; 
     } 

     private void TimerOnTick(object sender, EventArgs eventArgs) 
     { 
      for (var i = 0; i < currentValues.Length; i++) 
      { 
       this.currentValues[i] = this.random.Next(1, 7); 
      } 

      this.panel1.Invalidate(); 
     } 

     private void button1_Click(object sender, EventArgs e) 
     { 
      if (this.timer.Enabled) 
      { 
       this.timer.Stop(); 
      } 
      else 
      { 
       this.timer.Start(); 
      } 
     } 

     private void panel1_Paint(object sender, PaintEventArgs e) 
     { 
      e.Graphics.Clear(Color.White); 

      if (this.timer.Enabled) 
      { 
       for (var i = 0; i < currentValues.Length; i++) 
       { 
        e.Graphics.DrawImage(this.dice, new Rectangle(i * 70, 0, 60, 60), 0, (currentValues[i] - 1) * 60, 60, 60, GraphicsUnit.Pixel); 
       } 
      } 
     } 
    } 
} 

源是在這裏,如果有幫助:http://sdrv.ms/Wx2Ets