26

別のスレッドからWinFormsオブジェクトを呼び出すとform.show()、フォームは例外をスローします。メインのアプリスレッドに新しい表示可能なフォームを追加する方法はどこにありますか?それ以外の場合、現在実行中のスレッドを停止せずにフォームを開くにはどうすればよいですか?

これが私のサンプルコードです。スレッドを開始してから、そのスレッド内でいくつかの作業を実行しようとしています。作業が進むにつれて、フォームを表示します。

public void Main()
{
    new Thread(new ThreadStart(showForm)).Start();
    // Rest of main thread goes here...
}

public void showForm() 
{
    // Do some work here.
    myForm form = new myForm();
    form.Text = "my text";
    form.Show();
    // Do some more work here
}
4

4 に答える 4

36

呼び出し呼び出しを使用してみてください。

public static Form globalForm;

void Main()
{
    globalForm = new Form();
    globalForm.Show();
    globalForm.Hide();
    // Spawn threads here
}

void ThreadProc()
{
    myForm form = new myForm();
    globalForm.Invoke((MethodInvoker)delegate() {
        form.Text = "my text";
        form.Show();
    });
}

「invoke」呼び出しは、「私のスレッドではなく、スレッドでこのコードを実行してください」という形式を示します。その後、デリゲート内からWinFormsUIに変更を加えることができます。

Invokeの詳細については、http://msdn.microsoft.com/en-us/library/zyzhdc6b.aspxを参照してください。

編集:invokeを呼び出すには、すでに存在するWinFormsオブジェクトを使用する必要があります。ここでは、グローバルオブジェクトを作成する方法を示しました。それ以外の場合、他のWindowsオブジェクトがある場合は、それらも機能します。

于 2012-08-16T21:16:55.213 に答える
13

Application.Run()に電話した後に電話する必要がありますform.Show()。例えば:

public void showForm() 
{
    // Do some work here.
    myForm form = new myForm();
    form.Text = "my text";
    form.Show();
    Application.Run();
    // Do some more work here
}

理由の背後にある詳細については、このmsdnの投稿が役立つ場合があります。

于 2013-04-12T00:29:40.203 に答える
1

私の経験による最良の方法:

var ac = (ReportPre)Application.OpenForms["ReportPre"];
Thread shower = new Thread(new ThreadStart(() =>
    {
        if (ac == null)
        {                
            this.Invoke((MethodInvoker)delegate () {
                ac = new ReportPre();
                ac.Show();
            });       
        }
        else
        {
            this.Invoke((MethodInvoker)delegate
            {
                pictureBox1.Visible = true;
            });
            if (ac.InvokeRequired)
            {
                ac.Invoke(new MethodInvoker(delegate {
                    ac.Hide();
                    ac.Show();
                }));                          
            }
        }
    }));
shower.Start();
于 2018-07-30T19:19:57.957 に答える
-1

メインGUIスレッドがビジー状態のときにGUIを表示する場合(ロードバーなど)、次の操作を実行できます。

private void MethodWithLoadingBar()
{
    Thread t1 = new Thread(ShowLoading);
    t1.Start();
    // Do the Main GUI Work Here
    t1.Abort();
}

private void ShowLoading()
{
    Thread.Sleep(1000); //Uncomment this if you want to delay the display 
                        //(So Loading Bar only shows if the Method takes longer than 1 Second)
    loadingGUI = new LoadingGUI();
    loadingGUI.label1.Text = "Try to Connect...";
    loadingGUI.ShowDialog();
}

私のLoadingGUIは、パブリックラベルとスタイルがマーキーに設定されたプログレスバーを備えたシンプルなフォームです。

于 2020-07-14T10:11:29.340 に答える