teratail header banner
teratail header banner
質問するログイン新規登録

回答編集履歴

1

追記

2016/11/08 11:22

投稿

catsforepaw
catsforepaw

スコア5944

answer CHANGED
@@ -15,4 +15,60 @@
15
15
  g.FillRectangle(Brushes.Red, new Rectangle(0, 0, length, length));
16
16
  }
17
17
  pictureBox1.Invalidate(); // ←これを書かないと表示が更新されない
18
- ```
18
+ ```
19
+
20
+ ---
21
+ 追記
22
+
23
+ 連続する何らかのイベントに反応して重い処理をさせたい、ただし、間に合わない場合は端折ってもいい、というような処理をしたい場合は、私はだいたいこんなコードを書きます。
24
+
25
+ ビットマップを2枚用意するのは、いわゆるダブルバッファリングというやつです。ただ、描画処理がすごく重くてビットマップの生成やガベージコレクションにかかる時間など無視できるなら、毎回生成してPictureBoxにセットする方法でも問題ないかもしれません。
26
+ ```C#
27
+ private void Form1_Load(object sender, EventArgs e)
28
+ {
29
+ :
30
+ :
31
+
32
+ doubleBuffer[0] = new Bitmap(pictureBox1.Size.Width, pictureBox1.Size.Height);
33
+ doubleBuffer[1] = new Bitmap(pictureBox1.Size.Width, pictureBox1.Size.Height);
34
+ showIndex = 0;
35
+ backgroundWorker1.RunWorkerAsync();
36
+ }
37
+
38
+
39
+ private void numericUpDown1_Changed(object sender, EventArgs e)
40
+ {
41
+ lastLength = Convert.ToInt32(numericUpDown1.Value);
42
+ changeNotify.Set();
43
+ }
44
+
45
+ private int lastLength;
46
+ private AutoResetEvent changeNotify = new AutoResetEvent(false);
47
+ private Bitmap[] doubleBuffer = new Bitmap[2];
48
+ private int showIndex;
49
+
50
+ private void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e)
51
+ {
52
+ while(true)
53
+ {
54
+ changeNotify.WaitOne();
55
+ if(backgroundWorker1.CancellationPending )
56
+ break;
57
+
58
+ int length = lastLength;
59
+
60
+ // 表示中でない方のビットマップに対して描画処理を行う
61
+ int drawIndex = showIndex ^ 1;
62
+ var drawBuffer = doubleBuffer[drawIndex];
63
+
64
+ // 重い描画処理
65
+ :
66
+ :
67
+
68
+ // 描画したビットマップをPictureBoxに設定して表示を更新
69
+ pictureBox1.Image = drawBuffer;
70
+ showIndex = drawIndex;
71
+ this.Invoke(new Action(pictureBox1.Invalidate));
72
+ }
73
+ }
74
+ ```