简体   繁体   中英

How to display a text on a RichTextBox char by char?

I have Form1, RichTextBox1 and Button1 on my Form

To understand what i'm trying to do; take a look at this link , type in a facebook profile link and click on Hack Account AND SEE THE GREEN TEXT THAT APPEARS

I'm using the code below in C# to achieve what i want to do :

private void button1_Click(object sender, EventArgs e)
    {
        string myStr = "This is a test string to stylize your RichTextBox1";

        foreach (char c in myStr.ToCharArray()) {

            Thread.Sleep(100);
            richTextBox1.AppendText(c.ToString());

        }
    }

But it doesn't work, the text appears in the text box at one time; Not char by char!

The reason your code is showing all the text at once is using Thread.Sleep() keep the main Thread (the UI thread) suspended / sleep mode, so none of the Application message are processed on form & the form paint / drawing event are not doing the job as the UI thread is sleeping/suspended!


Solution 1: Use a helper Thread so that Thread.Sleep() dont make ur app go in non-responsive mode

public partial class Form1 : Form
{
    public Form1()
    {
        InitializeComponent();

    }

    private void button1_Click(object sender, EventArgs e)
    {
        string myStr = "This is a test string to stylize your RichTextBox1";

        ThreadPool.QueueUserWorkItem(ShowTextInInterval, myStr);
    }

    private void ShowTextInInterval(object state)
    {
        string mystr = state as string;
        if (mystr == null)
        {
            return;
        }
        for (int i = 0; i < mystr.Length; i++)
        {
            AppendNewTextToRichTextBox(mystr[i]);
            Thread.Sleep(100);
        }
    }

    private delegate void app_char(char c);
    private void AppendNewTextToRichTextBox(char c)
    {
        if (InvokeRequired)
        {
            Invoke(new app_char(AppendNewTextToRichTextBox), c);
        }
        else
        {
            richTextBox1.AppendText(c.ToString(CultureInfo.InvariantCulture));
        }
    }



}

Solution # 2 : Use a timer

public partial class Form1 : Form
{
    private Timer tbTimer = new Timer();
    string myStr = "This is a test string to stylize your RichTextBox1";
    private int charPos = 0;
    public Form1()
    {
        InitializeComponent();
        tbTimer.Interval = 100;
        tbTimer.Tick += TbTimerOnTick;

    }

    private void TbTimerOnTick(object sender, EventArgs eventArgs)
    {
        if (charPos < myStr.Length - 1)
        {
            richTextBox1.AppendText(myStr[charPos++].ToString(CultureInfo.InvariantCulture));
        }
        else
        {
            tbTimer.Enabled = false;
        }
    }

    private void button1_Click(object sender, EventArgs e)
    {
        tbTimer.Enabled = true;
    }




}

This is because the textbox is not refreshing whilst you are still running your code. Try putting this:

            foreach (char c in myStr.ToCharArray()) {

            Thread.Sleep(100);
            richTextBox1.AppendText(c.ToString());

richTextBox1.Refresh();
        }

The problem you are having is not in appending the text,

richTextBox1.AppendText(c.ToString()); //Good

works as expected but the issue is that you are putting the UI thread to sleep blocking the drawing of the text on the Rich Text Box.

Thread.Sleep(100); //Not so good

A quick workaround would be to add

richTextBox1.Refresh();

This forces the control to be redrawn after appending the text, but note your entire UI is still going to be frozen while the thread sleeping. A better solution maybe to use a System.Windows.Forms.Timer to accomplish your goal. This class triggers an event every specified interval. Some quick code,

    private System.Windows.Forms.Timer TextUpdateTimer = new System.Windows.Forms.Timer();
    private string MyString = "This is a test string to stylize your RichTextBox1";
    private int TextUpdateCount = 0;

    private void button1_Click(object sender, EventArgs e)
    {
        //Sets the interval for firing the "Timer.Tick" Event
        TextUpdateTimer.Interval = 100;
        TextUpdateTimer.Tick += new EventHandler(TextUpdateTimer_Tick);
        TextUpdateCount = 0;
        TextUpdateTimer.Start();
    }

    private void TextUpdateTimer_Tick(object sender, EventArgs e)
    {
        //Stop timer if reached the end of the string
        if(TextUpdateCount == MyString.Length) {
            TextUpdateTimer.Stop();
            return;
        }
        //AppendText method should work as expected
        richTextBox1.AppendText(MyString[TextUpdateCount].ToString());
        TextUpdateCount++;
    }

This updates the text box char by char without blocking the main thread and maintains usability on the front end.

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