C# 快速显示/隐藏WinForms GUI C的方法#

C# 快速显示/隐藏WinForms GUI C的方法#,c#,winforms,user-interface,show-hide,C#,Winforms,User Interface,Show Hide,我正在创建一个线程化的应用程序。我将GUI(公告:表单)作为单独的线程启动 该窗口将非常简约,只有一个输入框和一个按钮。在另一个线程上,Tcp客户端将运行,当它从TcpServer获取信息时,它应该将获取的信息传递到输入框中,并显示gui(以及最上面的窗口)。几秒钟后,gui应该隐藏自己并等待另一个tcp消息等等 public void setTextBox(string varText) { if (InvokeRequired) { textB

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

该窗口将非常简约,只有一个输入框和一个按钮。在另一个线程上,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线程填充文本框。现在唯一的问题是正确地显示和隐藏窗口。我一直在尝试许多解决方案,但总是出现问题。比如:

    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;
            }
        }
    }

有什么不好的吗

另一种方法是公开TCP线程对象上的事件。它可以定义一个事件,例如
receiveddata(…)
,然后GUI可以订阅该事件并更新自身,而无需执行任何
invokererequired
检查等。
更新:链接到C#事件教程
你可以试试

form.Hide();
但是请确保在创建表单的同一线程中显示/隐藏表单。hide()是隐藏表单的正确方法。我记得Form.Show()有问题,我模糊地记得必须使用Form.Activate()来正确恢复表单

this.Invoke(new MethodInvoker(this.hide()));

您已经正确地处理了线程编组(invokererequired和Invoke)。您还可以使用Form.BeginInvoke(),它是Form.Invoke的异步版本。这可能会更快。

使用
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);
string RunningProcess=Process.GetCurrentProcess().ProcessName;
Process[]processs=Process.GetProcessesByName(RunningProcess);
int SW_SHOW=5,SW_HIDE=0,SW_RESTORE=9,SW_SHOWNORMAL=1;
for(int a=0;a
您能否更具体地说明哪些不起作用?它不隐藏吗?不显示?二者都不够快?我现在不确定。我已经测试了这段代码,现在它似乎工作正常。我将用我在第一篇文章中发布的代码做更多的测试,并向大家报告。但也许有更好/更快的方法?如果TCP线程对象运行在与UI线程不同的线程上,则事件仍将调用该TCP对象线程上的窗体。invokererequired仍然是必需的(除非我弄错了)。(不过,事件是提供通知的更好方式)您可能是对的,我不确定gui端的事件处理程序是否会在gui线程中运行,我必须查找它才能确定。您能举例说明如何做到这一点吗?不知道从哪里开始?@MadBoy添加了事件教程的链接,这应该是一个很好的开始谢谢,我有你描述的问题。看看我在第一篇文章中发布的方法是否有效。