0

我的表单上有 Form1、RichTextBox1 和 Button1

了解我想要做什么;查看此链接,输入 facebook 个人资料链接并单击 Hack Account并查看出现的绿色文本

我在 C# 中使用下面的代码来实现我想要做的事情:

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

        }
    }

但是不行,文本一次出现在文本框中;不是一个字符一个字符!

4

3 回答 3

1

您的代码一次显示所有文本的原因是使用 Thread.Sleep() 保持主线程(UI线程)暂停/睡眠模式,因此没有任何应用程序消息在表单上处理,表单绘制/绘图事件是由于 UI 线程正在休眠/挂起,所以没有做这项工作!


解决方案 1:使用辅助线程,以便 Thread.Sleep() 不会使您的应用程序进入非响应模式

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



}

解决方案#2:使用计时器

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




}
于 2013-01-26T12:28:03.363 回答
0

这是因为当您仍在运行代码时,文本框不会刷新。试着把这个:

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

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

richTextBox1.Refresh();
        }
于 2013-01-26T12:29:50.237 回答
0

您遇到的问题不在于附加文本,

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

按预期工作,但问题是您让 UI 线程进入睡眠状态,阻止在富文本框中绘制文本。

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

一个快速的解决方法是添加

richTextBox1.Refresh();

这会强制在附加文本后重新绘制控件,但请注意,当线程休眠时,您的整个 UI 仍将被冻结。更好的解决方案可能是使用 aSystem.Windows.Forms.Timer来实现您的目标。此类每隔指定的时间间隔触发一个事件。一些快速代码,

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

这会在不阻塞主线程的情况下逐个字符地更新文本框,并保持前端的可用性。

于 2013-01-26T12:47:51.450 回答