简体   繁体   中英

How to make labels change in a C#.NET GUI-project

I'm making an application for a friend's birthday, where a window with changing compliments is supposed to pop up. The window freezes, however, and the labels don't change. I Googled it, and read something about using Backgroundworker in order to seperate the GUI-thread from the changing process. Still doesn't work.

This is my code:

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);
        }
    }
}

This is what's supposed to happen from the background, using a class I've named 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;}}
}

Still, nothing changes on my window. Everything is pretty much frozen, except for the text in the top-bar of the form itself, if I choose to uncomment form.Text = e;

Any advice?

You could achieve it using Timers instead of a BackgroundWorker.

It would probably look like this :

MainForm :

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();
    }
}

And the MessageHandler class :

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;
    }
}

To update the UI, use the ReportProgress method of the background worker. ReportProgress raises the ProgressChanged event and you can update your UI from there. Be sure to set the WorkerReportsProgress property of the backgroundworker to true.

Have a try with this: 1.) Copy Timer to Form 2.) Copy the following Code into the 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 ++;

}

Not the most elegant way, but it should work.

Try this code:

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

    }

    void theBackgroundWorker_doYourWork(object sender, DoWorkEventArgs e)
    {
         var w = sender as BackgroundWorker;

         List<String> stringList = GenerateComplimentTexts();
         Thread.Sleep(2000);
         w.ReportProgress(0, "Happy Birthday Goose!!!");
         w.ReportProgress(1, "Happy Birthday Goose!");      
         Thread.Sleep(3000);
         w.ReportProgress(2, "You are...");    
         Thread.Sleep(2000);
         foreach (String e in stringList)
         {
             w.ReportProgress(3, e);                
             Thread.Sleep(1000);
         }
         Thread.Sleep(3000);
         w.ReportProgress(3, "");  
         w.ReportProgress(2, FinalMessage);
    }

    void theBackgroundWorker_ProgressChanged(object sender, ProgressChangedEventArgs e)
    {

        var msg = e.UserState.ToString();
        switch (e.ProgressPercentage)
        { 
            case 0:
                 form.Text = msg;
                 break;
            case 1:
                hBDLabel.Text=msg;
                break;
            case 2:
                youAreLabel.Text =msg;
                break;
            case 3:
                mainLabel.Text=msg;
                break;

        }        
    }

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM