0

フォームにForm1、RichTextBox1、Button1があります

私がやろうとしていることを理解するために; このリンクを見て、Facebookのプロフィールリンクを入力し、ハックアカウントをクリックして、表示される緑色のテキストを確認してください

私は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 を使用して、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

あなたが抱えている問題は、テキストを追加することではありません、

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

期待どおりに機能しますが、問題は、UIスレッドをスリープ状態にして、リッチテキストボックスへのテキストの描画をブロックしていることです。

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

簡単な回避策は、追加することです

richTextBox1.Refresh();

これにより、テキストを追加した後にコントロールが強制的に再描画されますが、スレッドがスリープしている間、UI全体がフリーズすることに注意してください。より良い解決策は、おそらくSystem.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 に答える
0

これは、コードの実行中にテキスト ボックスが更新されないためです。これを入れてみてください:

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

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

richTextBox1.Refresh();
        }
于 2013-01-26T12:29:50.237 に答える