2016-10-05 9 views
0

現在、WindowsフォームとC#を使用しているゲームのレベルジェネレータを作成しています。私はBackgroundWorkerを持っているので、UIスレッドは保持されず、必要に応じて自分自身を更新することができます。私は現在BackgroundWorkers ReportProgress()関数を使ってプログレスバーを更新していますが、ジェネレータがどこにあるかに基づいてラベルを更新することもできます。つまり、「レベル2の初期化」、「レベル3のオブジェクトの配置」などです。WindowsフォームのラベルテキストをBackgroundWorkerから設定する方法

私はbackgroundWorkerからupdateProgress()関数を呼び出そうとしました(私はそれを渡し、フォームをGeneratorコンストラクタに渡します)。しかし、クロススレッドエラーが発生するため、動作しません。

public partial class mainForm : Form 
    { 
     LevelGen Generator; 
     List<Level> levelSet; 

     public mainForm() 
     { 
      InitializeComponent();; 
      Generator = new LevelGen(this, backgroundWorker, timer); 
     } 



     private void button_GenLevels_Click(object sender, EventArgs e) 
     {    
      if (!backgroundWorker.IsBusy) 
      { 
       progressBar.Value = 0; 

       backgroundWorker.RunWorkerAsync(); 
      } 
      else 
      { 
       backgroundWorker.CancelAsync(); 
      } 
     } 

     private void backgroundWorker_DoWork(object sender, DoWorkEventArgs e) 
     { 
      levelSet = Generator.startGeneration(); 
     } 

     public void updateProgress(int percentage, string currentWork) 
     { 
      label_processInfo.Text = percentage + " - " + currentWork; 
      backgroundWorker.ReportProgress(percentage); 
     } 

     private void backgroundWorker_ProgressChanged(object sender, ProgressChangedEventArgs e) 
     { 
      progressBar.Value = e.ProgressPercentage; 
     } 

     private void backgroundWorker_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e) 
     { 
      ListLevels(levelSet); 
     } 

    } 

そして、それは発電機の内部で、このように呼ばれる取得することになります。

public Level generateLevel(int noOfLevels, int noOfBoxes, int roomHeight, int roomWidth, int difficulty, int levelNum, int totalLevels) 
     { 
      bool generationSuccessful = false; 
      Level newLevel = new Level(); 
      float percentage; 
      int indProcesses = 2; 
      int totalProcesses = totalLevels * (indProcesses + 1); 

      while (!generationSuccessful) 
      { 
       newLevel = new Level(); 

       calculateProperties(ref noOfBoxes, ref difficulty, ref roomHeight, ref roomWidth); 

       percentage = (((levelNum * indProcesses)) * 100)/totalProcesses; 
       form.updateProgress((int)percentage, "Init Level " + levelNum); 

       initLevel(ref newLevel, roomHeight, roomWidth); 

       percentage = (((levelNum * indProcesses) + 1) * 100)/totalProcesses; 
       form.updateProgress((int)percentage, "Placing Patterns in Level " + levelNum); 

       placePatterns(ref newLevel, roomHeight, roomWidth); 

       generationSuccessful = true; 
      } 

      percentage = (((levelNum * indProcesses) + 2) * 100)/totalProcesses; 
      form.updateProgress((int)percentage, "Level " + levelNum + " Generated"); 

      return newLevel; 
     } 

は、どのように私はジェネレータ内から更新するために、Windowsフォームのラベルを教えてください?

+0

は、あなたがにデータを送信するために、ReportProgressメソッド、userStateのための第二のパラメータを使用することができますbackgroundWorker_ProgressChangedメソッド。次に、イベント引数e.UserStateから取得できます。 – Lidaranis

答えて

1

私はちょうど去ったコメントに基づいています。

public void updateProgress(int percentage, string currentWork) 
    { 
     label_processInfo.Text = percentage + " - " + currentWork; 
     backgroundWorker.ReportProgress(percentage,"New Label Value"); 
    } 
private void backgroundWorker_ProgressChanged(object sender, ProgressChangedEventArgs e) 
    { 
     progressBar.Value = e.ProgressPercentage; 
     string newLabelValue = (String)e.UserState; 
    } 

また、ユーザー状態はオブジェクトなので、任意のものを送信できます。

+0

ProgressChangedイベントのラベルTextを設定する必要があります –

+0

@エーザンSajjadはい。代わりに文字列newLabelValue =(String)e.UserState;彼はラベル値を設定する必要があります。しかし、それは彼がイベントの議論からそれを得る方法です。 – Lidaranis

+0

素晴らしい、それは素晴らしい仕事!それが今私が見る本当に明白な解決策でした。 –

0
.InvokeRequiredがスレッドセーフな方法でUI要素を更新する場合にも、デリゲートとチェックを使用することができます

delegate void SetTextCallback(string text); 
private void SetDebugText(string RxString) 
    { 
     if (this.btnDebug.InvokeRequired) 
     { 
      SetTextCallback d = new SetTextCallback(SetDebugText); 
      this.Invoke(d, new object[] { RxString }); 

     } 
     else 
     { 
      this.btnDebug.Text = RxString; 
     } 
    } 
関連する問題