Search code examples
c#.netwinformslabel

Updating a label using a for statement (typewriter effect)


I'm developing a game in Windows Forms (.NET-framework), and I want to add a typewriter effect to the text I'm displaying (so that it displays letter by letter). I'm using a for-loop for this. The text is displayed in a label.

I have 2 variables. 1 that holds all the text, and one that holds the text that needs to be printed out in the loop:

public string FullText;
private string CurrentText = "";

The label that I want to update with the loop is called: LblTextBottom

This is the method that gets executed when I click on the appropriate button:

public void TypeWriterEffect()
{
    for(int i=0; i < FullText.Length; i++)
    {
         CurrentText = FullText.Substring(0, i);

         LblTextBottom.Text = CurrentText;

         Thread.Sleep(10);
    }
}

This is the code that is activated when I click on the button to run the TypeWriterEffect method:

private void Button1_Click(object sender, EventArgs e)
{
    FullText = LblTextBottom.Text;
    ShowText();
}

It updates the Label, and the code works, but I don't see it updating in real time (the text doesn't get displayed letter by letter). I've tried using separate threads to update the control, but I didn't get that to work.

Ofcourse, I wouldn't be here if this code was working. But I don't know why it won't update. So any help would be greatly appreciated :)

P.s: This is what I'm looking for, but ofcourse without the UnityEngine classes and namespace (can't use those).

EDIT: Forgot to tell that when a button is clicked, a new string of text is loaded into the LblTextBottom, from a different .cs file.


Solution

  • If you write it generically, then you can have multiple typewriters going at the same time:

    private async void button1_Click(object sender, EventArgs e)
    {
        button1.Enabled = false;
    
        await TypeWriterEffect("This is some text to be `typed`...", LblTextBottom, 100);
    
        button1.Enabled = true;
    }
    
    private async void button2_Click(object sender, EventArgs e)
    {
        button2.Enabled = false;
    
        await TypeWriterEffect("Look mom, we're running at the same time!!!", label2, 200);
    
        button2.Enabled = true;
    }
    
    public Task TypeWriterEffect(string txt, Label lbl, int delay)
    {
        return Task.Run(() =>
        {
            for (int i = 0; i <= txt.Length; i++)
            {
                lbl.Invoke((MethodInvoker)delegate {
                    lbl.Text = txt.Substring(0, i);
                });                    
                System.Threading.Thread.Sleep(delay); ;
            }
        });            
    }
    

    Producing:

    enter image description here