質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.50%
C#

C#はマルチパラダイムプログラミング言語の1つで、命令形・宣言型・関数型・ジェネリック型・コンポーネント指向・オブジェクティブ指向のプログラミング開発すべてに対応しています。

Visual Studio

Microsoft Visual StudioはMicrosoftによる統合開発環境(IDE)です。多種多様なプログラミング言語に対応しています。

.NET Framework

.NET Framework は、Microsoft Windowsのオペレーティングシステムのために開発されたソフトウェア開発環境/実行環境です。多くのプログラミング言語をサポートしています。

Q&A

解決済

1回答

1722閲覧

C# テキストファイルの中身によってフォームの色を変更したい

AIR11451481019

総合スコア9

C#

C#はマルチパラダイムプログラミング言語の1つで、命令形・宣言型・関数型・ジェネリック型・コンポーネント指向・オブジェクティブ指向のプログラミング開発すべてに対応しています。

Visual Studio

Microsoft Visual StudioはMicrosoftによる統合開発環境(IDE)です。多種多様なプログラミング言語に対応しています。

.NET Framework

.NET Framework は、Microsoft Windowsのオペレーティングシステムのために開発されたソフトウェア開発環境/実行環境です。多くのプログラミング言語をサポートしています。

0グッド

0クリップ

投稿2021/11/26 02:47

使用環境はwindows10、Visual Studio2019(Windows Forms アプリ、.NET Framework、バージョン4.8)です。

テキストファイル(「a.txt」、画像)を1行ずつ読み込み、1なら黄色、0なら赤色にフォームの色を変更(色が変更される様子が目で見えるように)したいです。

イメージ説明

以下のように1行ずつ読み込むところまではできたのですが、どうやって色を変更するのかは検討がつきません。「if」「this.BackColor = color.RED」を使うのは予想できました。これをどう組み合わせればよいのでしょうか。ご教授頂けると幸いです。

using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Drawing; using System.Linq; using System.Text; using System.Threading.Tasks; using System.Windows.Forms; using System.IO; namespace _20211119_2 { public partial class Form1 : Form { public Form1() { InitializeComponent(); } private void button1_Click(object sender, EventArgs e) { if (openFileDialog1.ShowDialog() == System.Windows.Forms.DialogResult.OK) { label1.Text = openFileDialog1.FileName; string file = openFileDialog1.FileName; StreamReader sr = new StreamReader(file, Encoding.GetEncoding("SHIFT_JIS")); while (sr.EndOfStream == false) { string line = sr.ReadLine(); textBox1.Text += line + "\r\n"; } sr.Close(); } }

イメージ説明

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

BeatStar

2021/11/26 02:55

この仕様だとやめておいた方がいいかも。やってもいいですがおそらく無駄になる。 パパパパッと一気に切り替わり、最後のやつになるはずです。 やるなら、「次へ」とかみたいなボタンを配置して、そのボタンを押してから次のものに進むといった感じにしたほうがいいかと思います。(デバッガみたいに) それと、プログラミングは「こう書けばいい」というものではありません。
dodox86

2021/11/26 03:48

> 「if」「this.BackColor = color.RED」を使うのは予想できました。これをどう組み合わせればよいのでしょうか。 えと、プログラムのロジックが組めないということなのでしょうか。1行づつ読んでいるステップはあるのですから、そこに判定の処理を 入れれば良いのです。それが組めないというと、C#、ひいてはプログラミングの基本部分の学習不足です。 なお、実際にはただその処理を入れても簡単には色が変わる様子を観察することはできません。それを実現するのはUIの更新タイミングの話やタイマー、非同期など、別のトピックの知識が必要になります。
退会済みユーザー

退会済みユーザー

2021/11/26 04:16 編集

前回の質問でも言いましたが、入門書などで基礎を固める所から始めてください。 質問サイトは、まったく何も知らない人に1から10まで懇切丁寧に指導する場所ではありません。 [質問するときのヒント] https://teratail.com/help/question-tips [推奨していない質問] https://teratail.com/help/avoid-asking
fana

2021/11/26 06:25

「ファイルから1とか0とかいうデータを読み込むこと」と,「フォームの色を変えること」とは独立した問題なので,後者に関して困っているのであればそこに話題を絞る形で質問すると良いのではないでしょうか. 1とか0とかいう値が1つずつ与えられるとき → その値に従ってフォームの色を変える という話をすれば十分であるときには,「1とか0とかいう値はテキストファイルから読み出された」なんて話は雑音でしかないので.
guest

回答1

0

ベストアンサー

[質問への追記・修正の依頼]に書きましたが,
とりあえず「テキストファイルがどうの」いう部分についてはどうでもいいと見えるので,
以下の話では単純に仮のデータ
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}

投稿2021/11/26 07:36

編集2021/11/26 07:40
fana

総合スコア11634

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

AIR11451481019

2021/12/01 04:49

できました。ご回答ありがとうございます。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.50%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問