3

我正在创建一个线程化的应用程序。我将 GUI(公告:表单)作为单独的线程启动。

该窗口将非常简约,只有一个输入框,也许还有一个按钮。在另一个线程上将运行 Tcp 客户端,当它从 TcpServer 获取信息时,它应该将获取的信息传递到该输入框并显示 gui(和最顶层的窗口)。几秒钟后,gui 应该隐藏自己并等待另一个 tcp msg 等等。

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

此代码用于从 Tcp 线程填充文本框。现在唯一的问题是正确显示和隐藏窗口。尝试了许多解决方案,但总是出现问题。像:

    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

另一种方法是在 TCP 线程对象上公开事件。它可以定义一个事件,例如RecievedData(...)GUI 可以订阅该事件并自行更新,而无需进行任何InvokeRequired检查等。
更新:链接到 C# 事件教程
http://msdn.microsoft.com/en-us/library/aa645739 %28VS.71%29.aspx

于 2010-01-30T11:11:42.123 回答
1

你可以试试

form.Hide();

但请确保您从创建它们的同一线程中显示/隐藏表单

于 2010-01-30T11:12:29.340 回答
1
this.Invoke(new MethodInvoker(this.hide()));
于 2010-01-30T11:16:50.893 回答
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.BeginInvoke(),它是 Form.Invoke 的异步版本。那可能会更快。

于 2010-01-30T11:25:04.320 回答