[質問への追記・修正の依頼]に書きましたが,
とりあえず「テキストファイルがどうの」いう部分についてはどうでもいいと見えるので,
以下の話では単純に仮のデータ
var Data = new byte[] { 0, 1, 0, 1, 0, 1 };
に基づいて「フォームの色を変える」をやってみるとします.
↓のような順序で試しつつ,
そこに出てきた要素について調べる等してみればよいのではないかと思います.
(1)素直に書いてみる
まずは button1_Click
メソッド内に率直に以下を書いてみます.
CSharp
1var Data = new byte[] { 0, 1, 0, 1, 0, 1 }; //仮のデータ
2foreach (byte b in Data)
3{
4 this.BackColor = ( b==0 ? Color.Red : Color.Yellow );
5}
実行してボタンを押すと,フォームの色が即黄色になります.
foreach でループで処理しているのに色変更は1回分だけしか観測できません.
なぜでしょう?
(2)処理速度を疑う
前記の要因として
「処理があまりにも早すぎるために人の目には途中経過が見えないからではないか?」
と疑ってみます.
そこで,「色を変えるごとに少し待つ」ようにしてみましょう.
(Data
の部分は同一なので省略します)
CSharp
1foreach (byte b in Data)
2{
3 this.BackColor = ( b==0 ? Color.Red : Color.Yellow );
4 System.Threading.Thread.Sleep( 250 ); //少し待たせてみる
5}
実行すると… やっぱり途中経過は見えません.
なぜでしょう?
(3)再描画させてみる
とりあえず,「色を変えろ」と言うだけではダメっぽいので,
追加で「フォームの再描画もしろ」と言ってみましょう.
CSharp
1foreach (byte b in Data)
2{
3 this.BackColor = ( b==0 ? Color.Red : Color.Yellow ); //「色を変えろ」
4 this.Refresh(); //「再描画しろ」
5 System.Threading.Thread.Sleep( 250 ); //少し待たせてみる
6}
実行すると… 今度は途中経過が見えるかと思います.
なぜでしょう?
Refresh
についてググりましょう.そこを出発点として描画の仕組み等に関するいろんな話を学べるでしょう.
さて,とりあえず色の変化経過が見えるようにはなりましたが,
色が 赤→黄色→赤→黄色→… と変わっている間にフォームの位置を動かそうとか操作を試みてみれば,それができないことに気づくでしょう.
なぜでしょう?
試しに,this.Refresh();
を Application.DoEvents();
に書きかえてみれば,
色の変更処理中にもフォームを移動させたりすることができるようになります.
なぜでしょう?
Application.DoEvents
についてググりましょう.
おそらく,相応にネガティブな話を読むことができるでしょうが,そこからメッセージドリブンがどうのこうのという動作の仕組みに関するいろんな話を学べるでしょう.
(そしてあなたは Application.DoEvents
を用いることを棄却するでしょう)
(4)タイマーとか非同期処理とか…
運が良ければ,Application.DoEvents
についての否定的な話が書かれている場所には,より良い方法の話が書かれているかもしれません.
仮にそういうのが見つけられないとしても,この説のタイトルにある単語(「タイマー」「非同期」)を手掛かりに調べてみてください.
[余談]
私自身,C#は素人同然なので「非同期ってどう書くの?」というのが気になったので今ググってみました.
その結果としてどうにかこうにか書いてみたのが以下です.
実装としての良し悪しの判断はできませんが,どこかしら参考になるかもしれないので示しておきます.
CSharp
1//なんか "async" って書く
2private async void button1_Click(object sender, EventArgs e)
3{
4 button1.Enabled = false; //処理中に再度ボタン押されたりすると面倒そうなので防止
5
6 //非同期だそうで
7 await Task.Run(
8 () =>
9 {
10 var Data = new byte[] { 0, 1, 0, 1, 0, 1 };
11 foreach (byte b in Data)
12 {
13 this.BeginInvoke(
14 (Action<Color>)( (c)=>{ this.BackColor=c; } ),
15 ( b==0 ? Color.Red : Color.Yellow )
16 );
17 System.Threading.Thread.Sleep( 250 );
18 }
19 }
20 );
21
22 button1.Enabled = true; //処理が終わったらボタンを有効状態に戻す
23}