2

このコードがあるボタンをクリックすると、現在のフォームの上にダイアログが表示され、テキストが表示されます。1秒待ってから、テキストを変更して、最後に閉じます。

Form p = new Form();
p.ShowDialog();

p.Text = "Start.";
Thread.Sleep(1000);

p.Text = "Counting.";
Thread.Sleep(1000);

p.Text = "End.";
Thread.Sleep(1000);

p.Close();

ただし、実行するp.ShowDialog();と、フォームpが閉じられるまでコードが停止し、意図したとおりに機能しなくなります。これについてのガイダンスを得ることができますか?必ずしも解決策ではありませんが、少なくとも私がグーグルで検索できるいくつかのキーワードはありますか?

更新:問題とは無関係なビジネスロジックにアクセスしようとして直面している問題のため、実際の例の提供を遅らせています。しばらくお待ちください:)

解決策:私がしたことは、実際にはShow()の代わりに使用されShowDialog()ます。ビジネスロジックからフォームにアクセスすることができなかったので、BackgroundWorkerが便利で、それらの間で使用されていました。コードやプロジェクト構造のレイアウトを共有することはできませんが、結論として、受け入れられた回答のメインステートメントが解決策の鍵でした:)

4

4 に答える 4

3

それがShowDialog()のポイントです。モーダルフォームを作成し、完了するまで呼び出し元の関数に制御を戻しません。モーダルである必要がない場合は、.Show()を使用します。モーダルである必要がある場合は、Form Loadメソッドにコードを配置して、必要に応じてテキストを更新します。

于 2012-08-10T13:38:50.513 に答える
2

http://msdn.microsoft.com/en-us/library/c7ykbedk.aspx

上記のリンクから取得:

When this method is called, the code following it is not executed until after the dialog box is closed.

表示したいものをフォームに表示したい場合は、フォーム自体の中にコードを記述し、フォームのshoweventのeventhandlerでそれを実行する必要があります。

于 2012-08-10T13:39:04.307 に答える
2

ご覧のとおり、ShowDialogはダイアログが閉じられるまで戻らないブロッキングメソッドです。テキストを変更して遅延を処理するコードは、ダイアログ自体の中にある必要があります。

ただし、次の問題に注意する価値がありますThread.Sleep(1000)。UIスレッドから呼び出すと、アプリケーションは一度に1秒間応答しなくなります。これはおそらくあなたが目指しているものではありません!Timerこれをよりスムーズに処理するために、またはBackgroundWorkerクラスを調べることをお勧めします。

于 2012-08-10T13:40:20.420 に答える
1

これをチェックしてください:

public partial class Form2 : Form
{
    delegate void SetTextCallback(string text);
    delegate void CloseFormCallback();

    public Form2()
    {
        InitializeComponent();

        new Thread(DoMagic).Start();
    }

    public void DoMagic()
    {
        this.SetText("Start.");

        Thread.Sleep(1000);

        this.SetText("Counting.");
        Thread.Sleep(1000);

        this.SetText("End");

        Thread.Sleep(1000);

        this.CloseForm();
    }

    private void CloseForm()
    {
        if (this.InvokeRequired)
        {
            CloseFormCallback c = new CloseFormCallback(CloseForm);
            this.Invoke(c);
        }
        else
        {
            this.Close();
        }
    }

    private void SetText(string text)
    {
        if (this.label1.InvokeRequired)
        {
            SetTextCallback d = new SetTextCallback(SetText);
            this.Invoke(d, new object[] { text });
        }
        else
        {
            this.label1.Text = text;
        }
    }
}
于 2012-08-10T13:53:14.887 に答える