2008年12月30日火曜日

[.NET]Control.Updateの活用

たとえば100回ループする処理を実行中に状況を画面に表示したい場合、ループ内で単純にControl.Text属性を変更しても画面は更新されません。以下のbutton1_Clickがその例です。

回避方法としてすぐに思いつくのがDoEventsを使う方法です。以下のbutton2_Clickがその例です。しかしDoEventsは副作用があり、他の処理に影響を及ぼしてしまう場合があります。そのため、利用をできるだけ控えてきましたが、こういう処理の場合泣く泣くDoEventsを書いてきました。

しかし、button3_ClickのようにControl.Updateを使用する方法があること今日知りました。ということで確認の実装してみました。Control.Updateでも目的は達成できますね。

/// <summary>
/// 画面更新されない例
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void button1_Click(object senderEventArgs e)
{
    for (int i = 0i < 100i++)
    {
        Thread.Sleep(100);
        // textBox1に値を設定しているけど、ループ中画面は更新されない。
        textBox1.Text = i.ToString();
    }
    textBox1.Text = "Finish!!";

}

/// <summary>
/// Application.DoEventsで画面を更新する例
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void button2_Click(object senderEventArgs e)
{
    for (int i = 0i < 100i++)
    {
        Thread.Sleep(100);
        textBox1.Text = i.ToString();
        // DoEventsでメッセージQueueを処理する。
        Application.DoEvents();
    }
    textBox1.Text = "Finish!!";
}

/// <summary>
/// Control.Updateで画面を更新する例
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void button3_Click(object senderEventArgs e)
{
    for (int i = 0i < 100i++)
    {
        Thread.Sleep(100);
        textBox1.Text = i.ToString();
        // Control.Updateで処理する。
        textBox1.Update();
    }
    textBox1.Text = "Finish!!";
}

0 件のコメント: