0

私は友人の誕生日のアプリケーションを作成しています。そこでは、褒め言葉が変化するウィンドウがポップアップするはずです。ただし、ウィンドウはフリーズし、ラベルは変更されません。私はそれをグーグルで検索し、変更プロセスから GUI スレッドを分離するために Backgroundworker の使用について何かを読みました。それでもうまくいきません。

これは私のコードです:

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.Threading;

namespace ProjectL
{
    public partial class Form1 : Form
    {
        private MessageHandler theHandler = new MessageHandler();
        private BackgroundWorker theBackgroundWorker = new BackgroundWorker();
        public Form1()
        {
            InitializeComponent();
        }

        private void StartButton_Click(object sender, EventArgs e)
        {
            StartButton.Visible = false;
            theBackgroundWorker.DoWork += new DoWorkEventHandler(theBackgroundWorker_doYourWork);
            //theBackgroundWorker.RunWorkerCompleted += new RunWorkerCompletedEventHandler(theBackgroundWorker_doYourWork);
            theBackgroundWorker.RunWorkerAsync();        

            theHandler.RunMessage(hBDLabel, youAreLabel, mainLabel, this);
        }

        void theBackgroundWorker_doYourWork(object sender, DoWorkEventArgs e)
        {
            theHandler.RunMessage(hBDLabel, youAreLabel, mainLabel, this);
        }
    }
}

これは、MessageHandler という名前のクラスを使用して、バックグラウンドで発生するはずのことです。

class MessageHandler
{
    public List<String> GenerateComplimentTexts()
    {
        List<String> stringList = new List<String>();
        //Adding a bunch of compliments into a List<String>

        return stringList;
    }

    public void RunMessage(Label hBDLabel, Label youAreLabel, Label mainLabel, Form1 form)
    {
        List<String> stringList = GenerateComplimentTexts();
        Thread.Sleep(2000);
        form.Text = "Happy Birthday Goose!!!";
        hBDLabel.Text = "Happy Birthday Goose!";
        Thread.Sleep(3000);
        youAreLabel.Text = "You are...";
        Thread.Sleep(2000);
        foreach (String e in stringList)
        {
            mainLabel.Text = e;
            //form.Test = e

            Thread.Sleep(1000);
        }
        Thread.Sleep(3000);
        mainLabel.Text = "";
        youAreLabel.Text = FinalMessage;
    }

    private String _finalMessage = "FINAL MESSAGE";
    public String FinalMessage {get {return _finalMessage;}}
}

それでも、私のウィンドウでは何も変わりません。form.Text = e; のコメントを外すことを選択した場合、フォーム自体のトップバーのテキストを除いて、すべてがほとんど凍結されています。

何かアドバイス?

4

4 に答える 4

1

BackgroundWorker の代わりにTimersを使用して実現できます。

おそらく次のようになります。

メインフォーム :

public partial class Form1 : Form
{
    private Timer timer;
    private MessageHandler theHandler = new MessageHandler();

    public Form1()
    {
        InitializeComponent();
    }

    private void Form1_Load(object sender, EventArgs e)
    {
        timer = new Timer();
        timer.Interval = 1000;
        timer.Tick += TimerOnTick;
        // Initialize the other labels with static text here
    }

    private void TimerOnTick(object sender, EventArgs eventArgs)
    {
        theHandler.ShowNext(label1);
    }

    private void StartButton_Click(object sender, EventArgs e)
    {
        timer.Start();
    }
}

そして MessageHandler クラス:

public class MessageHandler
{
    private List<String> compliments = new List<string>();
    private int index = 0;

    public MessageHandler()
    {
        GenerateComplimentTexts();
    }

    private void GenerateComplimentTexts()
    {
        List<String> stringList = new List<String>();
        //Adding a bunch of compliments into a List<String>
        compliments = stringList;
    }

    public void ShowNext(Label label)
    {
        label.Text = compliments.ElementAt(index);
        index = (index >= compliments.Count - 1) ? 0 : index + 1;
    }
}
于 2013-05-14T18:51:47.417 に答える
0

UI を更新するには、バックグラウンド ワーカーの ReportProgress メソッドを使用します。ReportProgress は ProgressChanged イベントを発生させ、そこから UI を更新できます。backgroundworker の WorkerReportsProgress プロパティを必ず true に設定してください。

于 2013-05-14T18:46:25.867 に答える
0

これを試してみてください: 1.) タイマーをフォームにコピーします。 2.) 次のコードを timer1_tick-Event にコピーします。

private int _counter;
private int _currentIndex;

  private void timer1_Tick(object sender, EventArgs e)
    {
            switch (_counter)
            {
                case 1:
                   form.Text = "Happy Birthday Goose!!!";
                   hBDLabel.Text = "Happy Birthday Goose!";
                   break;

                case 2:
                    timer1.Interval = 3000;
                    break;
                case 3:
                    youAreLabel.Text = "You are...";
                    break;
                case 4:
                    if (stringlist.count = (_currentIndex -1))
                    {
                        timer1.Enabled = false;

                    }else {
                         mainLabel.Text = e;
                         timer1.Interval = 1000;
                       return;
                    }
                     break;
                    }

           _counter ++;

}

最もエレガントな方法ではありませんが、うまくいくはずです。

于 2013-05-14T19:03:34.293 に答える