C#プログレスバーの問題解決

このQ&Aのポイント
  • C#でプログレスバーを表示させる際に、ラベルの値が0%のままであり、プログレスバーが一気に100%になってしまう問題が発生しています。
  • ラベルの値を徐々に増やしていく方法を教えていただきたいです。
  • プログレスバーの設定に問題があり、ラベルの値が正しく表示されない状況です。
回答を見る
  • ベストアンサー

C# プログレスバーに関すること

先ほどご質問させて頂いた件で1つ解決していなかったのですが質問のほうを閉じてしまいました. なので,もう一度ご質問させて頂きます. ic += 1; //プログレスバーの設定 //最小値 int minimum = 0; //最大値 int years = iYearE - iYearS; int hours = iHourE-iHourS; int iiMinute = iiMinuteE-iiMinuteS; int Maximun = (years+1) * Maxmonth * Maxday * (hours+1) * (iiMinute+1); progressBar1.Style = ProgressBarStyle.Continuous; progressBar1.Minimum = minimum; progressBar1.Maximum = Maximun; progressBar1.Value = ic; label8.Text = (ic / Maximun)*100 + "%処理中"; if (ic/Maximun==1) { label8.Text = "終了"; 上記の様なプログラムを組んでプログレスバーを表示させているのですが,問題はラベルの中が 変動せずに,プログラスバーがすべてたまるまで0%で,たまった瞬間に100%になってしまいます. どうすればラベルのほうの数値を徐々に大きくしていけるのでしょうか? どなたかご教示お願いたします. }

質問者が選んだベストアンサー

  • ベストアンサー
回答No.1

整数を整数で割るとき、除数が被除数より大きいので結果がゼロになってしまっているということなので、 label8.Text = (ic / Maximun)*100 + "%処理中"; を、 label8.Text = (100*ic) / Maximun + "%処理中"; に変えればいいのではないでしょうか。

その他の回答 (1)

  • ONEONE
  • ベストアンサー率48% (279/575)
回答No.2

上記のコードをすべてfor文の中に入れるのでしたら無駄な計算が増えてしまうと思いますのでfor文の外に出したほうがいいと思います。 で、Application.DoEvents();を入れる必要があるのかなと思います。 このあたりを参考にされては。 http://dobon.net/vb/dotnet/programing/displayprogress.html http://www.atmarkit.co.jp/fdotnet/dotnettips/136doevents/doevents.html

関連するQ&A

  • C#プログラミング

    とても単純な事なのですが,例えばマクロだと ic=0 for j=1 To 100 ic=ic+1 next j という風に組むとicの値が1ずつ加算されていきますが,これをC#で書くと int ic for (j=1;j<=100;j++) { ic+=1; } でいいと思ったのですが,何かうまくいきません. 何がうまくいかないかといううと,プログレスバーが徐々にたまって行かず,処理が終わった 時にいきなり100になってしまいます. 下記にそのプログラムを転記しておきます.どなたかご教授頂けませんか? ic += 1; //プログレスバーの設定 //最小値 int minimum = 0; //最大値 int years = iYearE - iYearS; int hours = iHourE-iHourS; int iiMinute = iiMinuteE-iiMinuteS; int Maximun = (years+1) * Maxmonth * Maxday * (hours+1) * (iiMinute+1); progressBar1.Style = ProgressBarStyle.Continuous; progressBar1.Minimum = minimum; progressBar1.Maximum = Maximun; progressBar1.Value = ic; label8.Text = (ic / Maximun)*100 + "%処理中"; if (ic/Maximun==1) { label8.Text = "終了"; }

  • C# or VB プログレスバー

    プログレスバーで進行状況を表示する処理を入れています。 http://dobon.net/vb/dotnet/programing/progressdialog.html 上記のサイトをパクってとりあえず作ってみました。きちんとできているのですが 1つだけ問題があって try { ProgressDialog pd = new ProgressDialog(); //ダイアログのタイトルを設定 pd.Title = "カウントアップ"; //プログレスバーの最小値を設定 pd.Minimum = 0; //プログレスバーの最大値を設定 pd.Maximum = 10; //プログレスバーの初期値を設定 pd.Value = 0; //進行状況ダイアログを表示する pd.Show(this); //処理を開始 for (int i = 1; i <= 10; i++) { //プログレスバーの値を変更する pd.Value = i; //メッセージを変更する pd.Message = i.ToString() + "番目を処理中..."; //キャンセルされた時はループを抜ける if (pd.Canceled) break; //1秒間待機する(本来なら何らかの処理を行う) System.Threading.Thread.Sleep(1000); } //ダイアログを閉じる pd.Close(); } catch { MessageBox.Show("error"); } こんな感じで使い、プログレスバー表示中に例外が走るとMessageBoxがモーダレスで 表示されてしまいます。プログレスバー表示前だとモーダルのままです。 色々調べたところ原因は裏でスレッドが走っているからだと思います。たぶん・・ ところが対処法となると少々困っています。モーダルでMessageBoxを表示させたいのですが どうすればよいのでしょうか?教えてください。

  • VBでModule1からForm1のコントロールを操作したい

    VB.NETでForm1のProgressBarをForm1.VBからではなく外部Module1.vbのサブルーチンから操作する方法はありませんか。"Dim Form1 as New Form1"などとするともうひとつフォームが開いたりしてうまくいきません。現在、下記の様にしてもうひとつ別のForm2を開いてプログレスバーを表示しております。 できるなら、Form1だけで済ませたいと思っております。 勉強不足でわかりません。どなたか教えてください。 Form2.Show() Form2.ProgressBar1.Minimum = 0 Form2.ProgressBar1.Maximum = 学習回数 Form2.ProgressBar1.Visible = True For 繰り返し = 1 To 学習回数 Form2.ProgressBar1.Value = 繰り返し Form2.lbl解析中.Text = 繰り返し Form2.Label1.Update() Form2.lbl解析中.Update()      ****処理**** Next

  • Labelでプログレスバーの表示

    いつも大変お世話になっております。 動作が重いマクロ、プログラムが多いため、 プログレスバーを表示させたいと思っています。 フォームを20個以上準備しており、 それに対し プログレスバーを使いたいのが10個程度であり、 今後増えるかもしれません。 そのため、標準モジュールを利用し、簡単に プログレスバーを設定できないかと思っています。 '=================== 【標準モジュール Module1】 Sub Bar_progressBarData(Byval UserFormName as string, Byval MaxData as Long,LabelName as string) 'UserFormName 引用するところ?のユーザーフォーム名 'MaxData バーの最大値設定 'LabelName バー表示するラベル名 'ProgressBarの初期設定などをやる End sub '------------------------- Sub Bar_progressBarInt(Byval UserFormName as string, Byval MaxData as Long,LabelName as string) 'UserFormName 引用するところ?のユーザーフォーム名 'MaxData バーの最大値設定 'LabelName バー表示するラベル名 'ProgressBarの値を増やしていく(増加させていくプログラム) End sub '================= 【UserForm Test】 Sub DataChangeGraph() 'ループが多いデータ Call Bar_progressBarInt(Me.Name,10,"Label1")'バーの値を増加させていく End Sub Private Sub UserForm_Initialize() Call Bar_progressBarData(Me.Name,10,"Label1")'初期設定(例として、max10にしました) End Sub Maxの値、プログレスデータに使用する値は グローバルに設定してしまうというのも楽かもしれません。 しかし、この続きの肝心なプログラムが分かりません。 「プログレスバーの作り方」 h ttp://www.h3.dion.ne.jp/~sakatsu/ProgressBarTopic.htm このサイトが良いと評判でしたので、 見ましたが何をしているのか良く分かりませんでした。 Widthを設定? Dim sngBarMaxWidth As Single? そして、私がやりたいこととは少し違うようです。 私がやりたいのは、フォーム上に毎回プログレスバー用のプログラムを書くのが面倒だったので、 標準モジュールとしてSubプロシージャを作成(日本語? そして、それを引用してプログレスバーの設定を簡単に終わらせる ということがしたかったのです。 できれば、ラベルなど Excelに標準で備わっているものを使用したいと思っています。 プログレスバー専用のツール(参照設定などを用いるもの) はその後にエラーが出たとき困るので、使いたくありません。 なんとなく伝わったでしょうか? 回答よろしくお願い致します。 Excel2003 VBA

  • [C#.net]スレッド化された別フォームのプログレスバーの操作方法について

    こんちは。最近C#をやり始めて行き詰まったので質問致します。 質問内容に対する答えをお持ちの方がいらっしゃいましたら、お暇な時にでもお答えください。 public Class SumLoop { public Keisan(int Cnt, string Msg) {   // (1)プログレスバーのフォーム生成時に変数Cntをプログレスバーの最大値、変数Msgをフォームのタイトルに設定したい。   FormProgress FrmPro = new FormProgress();  Thread thread = new Thread(new ThreadStart((2)) );   thread.Start();   for(int i=0; i<Cnt; i++) {   // (3)このiがインクリメントする度にプログレスバーのValueを増やしたい   // FrmPro.SetProgressValue(i) // これだとコンパイラに怒られた    // ここに主な処理   } } public partial class FormProgress : System.Windows.Forms.Form {  public FormDfmProgress() { InitializeComponent(); }  // (3)これではダメみたい  public void SetprogressValue(int iValue) {   progressBar1.Value = iValue;   progressBar1.Refresh();  }  // (4)他のイベントが必要? } ざっと汚いコードを書きましたが具体的にお知恵を貸して頂きたいところは (1)のフォーム生成時のパラメータをどう与えるのか? インスタンス作成の際にここで言うFormDfmProgressをthisで継承させオーバーロードさせれば良いんでしょうか? (2)プログレスバーのフォームを表示させたいだけなのですが、.ShowDialog()では怒られ、.Showでは即座にフォームが消えたりでどうにもなりません。スレッドが消えるまで表示させるにはどうしたらいいでしょう? (3)フォーム側のプログレスバーのValueなり、変数なりをスレッド稼動中に更新させるにはどうしたらいいでしょうか? (4)は、大して気にしていないのですが、これが致命的に足りない!とかいうのがあればご指導願います。 以上長々となりましたが、お暇な方お力を御貸しください

  • C言語初心者です。書いたプログラムを採点して下さい

    入力された0~100までの10個の数値から、 最小値と最大値を表示するプログラムを書きました。 #include <stdio.h> int getmin(int * pvalue); int getmax(int * pvalue); int main(void) {     int i,value[10];     int minimum,maximum;     printf("0~100の範囲で10個の数値を入力してください:\n");     for(i=0;i<10;i++){         scanf("%d",&value[i]);         if(value[i] < 0 || value[i] > 100)         {             printf("0~100の範囲です:\n");             scanf("%d",&value[i]);         }     }     minimum = getmin(value);     maximum = getmax(value);     printf("最小値は%d\n",minimum);     printf("最大値は%d\n",maximum);     return 0; } int getmin(int * pvalue) {     int i=0,j;     for(j=1;j<10;j++)     {         while(pvalue[i] > pvalue[j]){i++;}     }     return pvalue[i]; } int getmax(int * pvalue) {     int i=0,j;     for(j=1;j<10;j++)     {         while(pvalue[i] < pvalue[j]){i++;}     }     return pvalue[i]; } 正常に作動はしましたが、 記述に無駄が多い、分かりづらい などあればご指導いただけますか? よろしくお願いします。

  • C#のフォームについて

    http://dobon.net/vb/dotnet/programing/progressdialog.html 上記のサイトを元にプログラムを作成したのですがうまくいきません。 ProgressDialog pd = new ProgressDialog(); //ダイアログのタイトルを設定 pd.Title = "カウントアップ"; //プログレスバーの最小値を設定 pd.Minimum = 0; //プログレスバーの最大値を設定 pd.Maximum = 10; //プログレスバーの初期値を設定 pd.Value = 0; //進行状況ダイアログを表示する pd.Show(this); //処理を開始 for (int i = 1; i <= 10; i++) { //プログレスバーの値を変更する pd.Value = i; //メッセージを変更する pd.Message = i.ToString() + "番目を処理中..."; //キャンセルされた時はループを抜ける if (pd.Canceled) break; //時間のかかる処理 //時間のかかる処理 //時間のかかる処理 } //ダイアログを閉じる pd.Close(); 上記のコードの場合、ループ毎の最初にキャンセルかどうかの条件が書かれているため、ループ処理の途中にキャンセルを押してもきかない時があります。 処理中は常にキャンセルかを監視し、押されたらすぐにキャンセルできるようにしたいのですが、どのようにしたらいいのでしょうか。

  • C#のlabelの表示について

    C#のlabelの表示について カテ違いですが、C#のカテゴリがないのでここで質問させていただきます。 以下の時刻を表示するプログラムを作成したのですが、        //現在の時刻を取得  DateTime dt = DateTime.Now; int Second_1 = dt.Second % 10; int Second_2 = dt.Second / 10; int Minute_1 = dt.Minute % 10; int Minute_2 = dt.Minute / 10; int Hour_1 = dt.Hour % 10; int Hour_2 = dt.Hour / 10; label1.Text = Second_1.ToString(); label2.Text = Second_2.ToString(); label3.Text = Minute_1.ToString(); label4.Text = Minute_2.ToString(); label5.Text = Hour_1.ToString(); label6.Text = Hour_2.ToString(); if (int.Parse(label1.Text) == 0 && int.Parse(label2.Text) == 0) { int a; for (a = 0; a < 10; a++) { pictureBox4.Top += 1; System.Threading.Thread.Sleep(30); } for (a = 0; a < 50; a++) { pictureBox4.Top += 5; System.Threading.Thread.Sleep(10); } pictureBox4.Top = 12; } label1は「秒」の1の位、 label2は「秒」の10の位、 pictureBox4は「分」の1の位の画像を表示しています。 pictureBoxとlabelを重ねて、画像の上に時刻を表示しています。 秒が0になったとき(分の位が一つ上がるとき)、 分の位の画像を移動させて(forループ2つ)再び元の位置に戻しているのですが(pictureBox4.Top = 12;) そのとき秒が「00」とはならず「59」のままで、このループが終わると「00」を飛ばして「01」となります。 ちなみにこの部分はタイマーで0.2秒ごとに回しています。 原因がわかりませんので、ご教授願います。 また、ループには概算で0.8秒かかりますが、この間、タイマーの呼び出しは実行されているのでしょうか? 加えて、pictureBox4.Topの値を動かしていますが、重ねて配置しているlabelも一緒に動いてくれます。 いろいろなサイト様を参考に、 this.label3.Parent = this.pictureBox4; と親コントロールをFormから変更したのですが、このためでしょうか? 変な表現がありましたらご容赦ください。 よろしくお願いします。

  • vb.net コピーの進捗をプログレスバーで

    質問ばかりでもうしわけないのですが タイトルにあるようにコピーの状況を プログレスバーで表示できたらなと思い作成したのですが うまく動きません。 プログレスバー自身単独では動くのですがコピーと合わせると フリーズしてしまいます。 プログラミング経験と発想力が乏しいのでご教授いただけたら幸いです Private Sub Bt_1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Bt_1.Click Dim fname1 As String = "C:\フォルダ名A" Dim fname2 As String = "C:\フォルダ名B" Dim ber1 As Integer If IO.Directory.Exists(fname1) = True Then Me.Lb_1.Text = "テキスト文字" For ber1 = 0 To 20 Me.ProgressBar1.Value = ber1 System.IO.File.Copy("コピー元テキストファイルA", "コピー先テキストファイルA", True) My.Computer.FileSystem.CopyDirectory("コピー元フォルダA", "コピー先フォルダA", True) My.Computer.FileSystem.CopyDirectory("コピー元フォルダB", "コピー先フォルダB", True) Next ber1 If IO.Directory.Exists(fname2) = True Then System.IO.File.Copy("コピー元ファイルB", "コピー先ファイルB", True) End If MessageBox.Show("終了報告テキスト", "タブ名") ' System.IO.Directory.Delete("コピー元", True) Me.ProgressBar1.Value = 0 Application.Exit() こんな感じで作成しております。 ファイル自身が1GBぐらいあるので フリーズしていないかプログレスバーや%表示でしらせたいので 教えていただけると助かります。 よろしくお願いします。

  • C# プログラム

    下記のプログラムを組んだのですが,for Dが1回しかまわりません. int[] Mo = new int[12]; #region Month ///<summary> ///月の定義 ///<summary/> Mo[0] = 4; Mo[1] = 5; Mo[2] = 6; Mo[3] = 7; Mo[4] = 8; Mo[5] = 9; Mo[6] = 10; Mo[7] = 11; Mo[8] = 12; Mo[9] = 1; Mo[10] = 2; Mo[11] = 3; #endregion int hh = f1.Ye; int ic = 0; for (int D = 0; D <= 11; D++) { int hye = hh; MessageBox.Show(D.ToString()); if (Mo[D] < 4) { hye = hh + 1; } int hmo = Mo[D]; // 2004年02月の日数を取得する int iDaysInMonth = DateTime.DaysInMonth(hye,hmo); //日数を積算 ic=ic + 31; int Sic = 31*D + 1; int Dic = 0; for (int N = Sic; N <= ic; N++) { Dic = Dic + 1; //必要な変数を宣言する DateTime dateValue = new DateTime(hye, hmo, Dic); // 曜日を取得する DayOfWeek uWeekday = dateValue.DayOfWeek; string W = ("日月火水木金土").Substring(int.Parse(dateValue.DayOfWeek.ToString("d")), 1); //MessageBox.Show(W.ToString()); string NI = Convert.ToString(Dic); if (Dic > iDaysInMonth) { NI = ""; W = ""; } //Labelに文字を入力。 string h = "label" + N; string hY = "label" + (N + 372); //MessageBox.Show(hY.ToString()); //日数を記入 Control[] cs = this.Controls.Find(h, true); ((Label)cs[0]).Text = NI; //曜日の記入 Control[] css = this.Controls.Find(hY, true); ((Label)css[0]).Text = W; } } いろいろ調べて //必要な変数を宣言する DateTime dateValue = new DateTime(hye, hmo, Dic); こいつが何らかの影響を及ぼしていることまではつかんだのですが,何が悪いのか,また, どうすれば改善できるのか解らず困っています. ご教授よろしくお願いいたします.

専門家に質問してみよう