【问题标题】:Way to quickly show/hide WinForms GUI C#快速显示/隐藏 WinForms GUI C# 的方法
【发布时间】:2011-01-11 04:14:55
【问题描述】:

我正在创建一个线程化的应用程序。我将 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;
            }
        }
    }

有什么不好的吗?

【问题讨论】:

  • 您能否更具体地说明什么不起作用?它不隐藏吗?不显示?两个都?不够快?
  • 嗯,我现在不确定。我已经对这段代码进行了一些巧妙的测试,现在它似乎可以正常工作了。我将使用我在第一篇文章中发布的代码进行更多测试并报告回来。但也许有更好/更快的方法?

标签: c# winforms user-interface show-hide


【解决方案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);

【讨论】:

  • 谢谢,我遇到了你描述的问题。看看我在第一篇文章中发布的方法是否可以正常工作。
【解决方案2】:

你可以试试

form.Hide();

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

【讨论】:

    【解决方案3】:
    this.Invoke(new MethodInvoker(this.hide()));
    

    【讨论】:

      【解决方案4】:

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

      【讨论】:

      • 如果 TCP 线程对象运行在与 UI 线程不同的线程上,事件仍将调用该 TCP 对象线程上的表单。 InvokeRequired 仍然是必需的(除非我弄错了)。 (虽然事件是提供通知的更好方式)
      • 你可能是对的,我不确定 gui 端的事件处理程序是否会在 gui 线程中运行,我必须查一下才能确定。
      • 你能举例说明如何做到这一点吗?不知道从哪里开始?
      • @MadBoy 添加了事件教程的链接,这应该是一个好的开始
      【解决方案5】:

      Form.Hide() 是隐藏表单的正确方法。我记得有 Form.Show() 的问题,我有一个模糊的记忆,必须使用 Form.Activate() 才能让表单正确恢复。

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

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2022-11-10
        • 2015-07-15
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2011-07-01
        • 1970-01-01
        相关资源
        最近更新 更多