C# 快速显示/隐藏WinForms GUI C的方法#
我正在创建一个线程化的应用程序。我将GUI(公告:表单)作为单独的线程启动 该窗口将非常简约,只有一个输入框和一个按钮。在另一个线程上,Tcp客户端将运行,当它从TcpServer获取信息时,它应该将获取的信息传递到输入框中,并显示gui(以及最上面的窗口)。几秒钟后,gui应该隐藏自己并等待另一个tcp消息等等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
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添加了事件教程的链接,这应该是一个很好的开始谢谢,我有你描述的问题。看看我在第一篇文章中发布的方法是否有效。