• ベストアンサー

[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)は、大して気にしていないのですが、これが致命的に足りない!とかいうのがあればご指導願います。 以上長々となりましたが、お暇な方お力を御貸しください

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

  • ベストアンサー
noname#259269
noname#259269
回答No.3

>Keisanメソッドが言わばMainのような形で、フォームやらその他のメソッドは常にKeisanメソッドの従としたいのでした。 フォームに貼り付いたコントロールには、プライマリスレッドからしかアクセスできないのですよ。だから、redfox63 さんのような回答になる訳です。

mindatg
質問者

お礼

なるほど、コントロールにはそんな制約があったんですか。 初めて知りました。どおりでそんな感じの解説やサンプルコードが見つからなかった訳か、と恥ずかしい余りです。 ありがとうございました。

その他の回答 (2)

  • redfox63
  • ベストアンサー率71% (1325/1856)
回答No.2

この部分は スレッド作成するイベント側で記述します Thread thread = new Thread(new ThreadStart((2)) ); thread.Start(); (2)はデリゲートを指定しますので 引数なしのデリゲート用関数を用意します FormProgressのキャプション(タイトル)の変更は Textプロパティでできます Public Class SumLoop {   public int nCnt = 0;   public String sMsg = "";   public void keisan()   {     FromProgress frm = new FormProgress();     frm.Text = sMsg;     frm.setProgrssMax( nCnt );     frm.Show();     for( int i = 0; i < nCnt; i++ ) {       frm.setProgressValue( i );       Thread.Sleep( 10 );     }   } } ProgessBarの最大値は Maximumプロパティを操作するので 外部から扱えるようにメソッドを追加しましょう public void setProgressMax( int nMax ) {   progressBar1.Maximum = nMax; } スレッド起動側のイベントで SumLoop objSL = new SumLoop(); objSL.nCnt = 200; objSL.sMsg = "タイトル"; Thread thread = new Thread( new ThreadStart( objSL.Keisan ) ); thread.Start(); といった具合でしょう

mindatg
質問者

お礼

わざわざコードまで付けて頂いて恐縮です。 ただ、こちらの方法では計算(Keisanメソッド)をスレッド化するようです。 私のコードと質問内容の書き方が悪いといえばそれまでですが Keisanメソッドが言わばMainのような形で、フォームやらその他のメソッドは常にKeisanメソッドの従としたいのでした。 後学の参考とさせて頂きます。

noname#259269
noname#259269
回答No.1

こういうときには、BackgroundWorker という便利なものがありますので、そちらを使いましょう。 http://www.atmarkit.co.jp/fdotnet/dotnettips/436bgworker/bgworker.html http://msdn.microsoft.com/ja-jp/library/system.componentmodel.backgroundworker(VS.80).aspx

mindatg
質問者

お礼

ご意見ありがとうございます、不思議なことにリンクが紫色でした。 ただ、今回教えて頂きたい事とはちょっと違うようです。