3

スレッド化されたアプリを作成しています。別スレッドとして GUI (Announce : Form) を始めました。

そのウィンドウは、入力ボックスが 1 つとボタンが 1 つある非常に最小限のものになります。別のスレッドでは Tcp クライアントが実行されており、TcpServer から情報を取得すると、取得したものをその入力ボックスに渡し、GUI (および最上位のウィンドウ) を表示する必要があります。数秒後、GUI は非表示になり、別の tcp メッセージなどを待つ必要があります。

    public void setTextBox(string varText) {
        if (InvokeRequired) {
            textBox.BeginInvoke(new textBoxCallBack(setTextBox), new object[] {varText});
        } else {
            textBox.Text = varText;
        }
    }

このコードは、Tcp スレッドから textBox を埋めるために使用されます。唯一の問題は、ウィンドウの表示と非表示を適切に行うことです。多くのソリューションを試してきましたが、常に何かがうまくいきませんでした。お気に入り:

    private void windowStateChange(string varState) {
        if (InvokeRequired) {
            Invoke(new WindowStateChangeCallBack(windowStateChange), new object[] {varState});
        } else {
            if (varState == "Hide") {
                //Hide();
                // TopMost = false;
                //TopMost = varState != FormWindowState.Minimized;
            } else {
                //Show();
                //MessageBox.Show("TEST1");
            }
        }
    }

    public void windowStateChangeDiffrent(FormWindowState varState) {
        if (InvokeRequired) {
            Invoke(new WindowStateChangeCallBack(windowStateChange), new object[] {varState});
        } else {
            WindowState = varState;
           // Hide();
            TopMost = varState != FormWindowState.Minimized;
        }
    }

これを行うための最良のアプローチは何ですか(そして時間が重要なので最速です)?

うまくいくように見える回答1:

    private static void windowStateChange(string varState) {
        if (mainAnnounceWindow.InvokeRequired) {
            mainAnnounceWindow.BeginInvoke(new StateCallBack(windowStateChange), new object[] {varState});
        } else {
            if (varState == "Hide") {
                mainAnnounceWindow.Hide();
                mainAnnounceWindow.TopMost = false;
            } else {
                mainAnnounceWindow.Show();
                mainAnnounceWindow.TopMost = true;
            }
        }
    }

それについて何か悪いことはありますか?

4

5 に答える 5

1
this.Invoke(new MethodInvoker(this.hide()));
于 2010-01-30T11:16:50.893 に答える
1

もう 1 つの方法は、TCP スレッド オブジェクトでイベントを公開することです。GUIがそのイベントにサブスクライブし、チェックなどRecievedData(...)を行うことなく自分自身を更新できるように、イベントを定義できます。 更新:C#イベントチュートリアルへのリンクhttp://msdn.microsoft.com/en-us/library/aa645739 %28VS.71%29.aspxInvokeRequired

于 2010-01-30T11:11:42.123 に答える
1

あなたは試すかもしれません

form.Hide();

ただし、フォームを作成した同じスレッドからフォームを表示/非表示にするようにしてください

于 2010-01-30T11:12:29.340 に答える
1

フォームを非表示にしてform.Hide()も問題はありません。

ただし、フォームを再度表示しても、常に機能するとは限りません。したがって、同じ問題が発生した場合は、次のようなものを使用できます。

string RunningProcess = Process.GetCurrentProcess().ProcessName;
Process[] processes = Process.GetProcessesByName(RunningProcess);

int SW_SHOW = 5, SW_HIDE = 0, SW_RESTORE = 9, SW_SHOWNORMAL = 1;

    for (int a = 0; a < processes.Length; a++)
        {
         IntPtr hWnd = processes[a].MainWindowHandle;

         ShowWindowAsync(hWnd, SW_RESTORE);
         ShowWindowAsync(hWnd, SW_SHOWNORMAL);
         ShowWindowAsync(hWnd, SW_SHOW);
         SetForegroundWindow((int)hWnd);
        }

        //Required Win32 API imports           
        [System.Runtime.InteropServices.DllImport("user32.dll", SetLastError = true)]
        static extern bool ShowWindowAsync(IntPtr windowHandle, int cmd);

        [System.Runtime.InteropServices.DllImportAttribute("User32.dll")]
        private static extern IntPtr SetForegroundWindow(int hWnd);
于 2010-01-30T13:33:21.283 に答える
0

Form.Hide() は、フォームを非表示にする正しい方法です。Form.Show() で問題が発生したことを覚えています。フォームを正しく復元するには、Form.Activate() も使用する必要があるという漠然とした記憶があります。

スレッドのマーシャリングを正しく処理しています (InvokeRequired および Invoke)。Form.Invoke の非同期バージョンである Form.BeginInvoke() を使用することもできます。その方が早いかもしれません。

于 2010-01-30T11:25:04.320 に答える