这篇文章是Way to quickly show/hide WinForms GUI C#的延续,因为在这种特殊情况下它对我不起作用。
我有两个问题:
1是mainAnnounceWindow gui应该启动隐藏,稍后调用时:windowStateChange(“Show”)它应该显示,通过windowStateChange(“Hide”)它应该隐藏。它不能正确地执行,因为当我启动应用程序时,它可见为0.5秒(我看到它闪烁)。有没有办法让它开始隐藏而不会眨眼半秒钟。
2是从myThreadHandler(Queue.Work)调用windowStateChange时无法正常工作。
internal class Program {
public delegate void StateCallBack(string varState);
public static readonly Announce mainAnnounceWindow = new Announce();
public static readonly Thread myThreadGuiAnnounce = new Thread(showGuiAnnounce);
public static readonly Thread myThreadTcpClient = new Thread(threadTcpClient);
public static readonly Thread myThreadUdpMonitor = new Thread(threadUdpMonitor);
public static readonly Thread myThreadHandler = new Thread(Queue.work);
public static void Main()
{
myThreadGuiAnnounce.Start();
myThreadTcpClient.Start();
myThreadUdpMonitor.Start();
myThreadHandler.Start();
windowStateChange("Hide");
while (true) {
Thread.Sleep(1000);
}
}
public static void windowStateChange(string varState) {
if (mainAnnounceWindow.InvokeRequired) {
mainAnnounceWindow.Invoke(new StateCallBack(windowStateChange), new object[] {varState});
} else {
if (varState == "Hide") {
mainAnnounceWindow.Hide();
mainAnnounceWindow.TopMost = false;
} else {
mainAnnounceWindow.Show();
mainAnnounceWindow.TopMost = true;
}
}
}
private static void showGuiAnnounce() {
mainAnnounceWindow.ShowDialog();
}
}
另一堂课:
public class Queue : IDisposable {
public static void work() {
while (true) {
string task = null;
lock (locker)
if (tasks.Count > 0) {
task = tasks.Dequeue();
if (task == null) {
return;
}
}
if (task != null) {
//MessageBox.Show("Performing task: " + task);
Program.mainAnnounceWindow.setLogTextBox(task);
Program.mainAnnounceWindow.setLogTrayTip(task);
Program.windowStateChange("Show");
Thread.Sleep(5000); // simulate work...
Program.windowStateChange("Hide");
} else {
wh.WaitOne(); // No more tasks - wait for a signal
}
}
}
}
问题在于:
Program.windowStateChange("Show");
Thread.Sleep(5000); // simulate work...
Program.windowStateChange("Hide");
当我调用Program.windowStateChange(“Show”)时;从其他线程内部gui显示但不完全..就像我可以看到它想要显示,但事实并非如此。就像一个应用程序的挂起。但是当Thread.Sleep(5000)通过应用程序隐藏时。
通话:
Program.mainAnnounceWindow.setLogTextBox(task);
Program.mainAnnounceWindow.setLogTrayTip(task);
没问题。 BaloonTip显示,只是Gui没有正确显示。我做错了什么。
哦,当然我做了一些剪切/粘贴,所以它可能会遗漏一些东西。如果有必要添加一些东西让我知道。
关于,
MadBoy
答案 0 :(得分:1)
您的问题是您正在从非ui线程访问ui对象,这是不允许的。您需要将一个包含您要执行的操作的委托传递给其中一个ui控件(可能是您的表单对象)上的Invoke或BeginInvoke方法。
答案 1 :(得分:1)
问题是你的主线程被锁定了,因为你添加了这个:
while (true) {
Thread.Sleep(1000);
}
这将阻止窗口线程适当地接收和处理Windows消息(例如显示和隐藏)。
您还希望使用mainAnnounceWindow.Show()
,而不是mainAnnounceWindow.ShowDialog()
,因为这会阻止控件正确返回主线程。您应该在主程序中调用Application.Run(mainAnnounceWindow)
:
public static void Main()
{
myThreadGuiAnnounce.Start();
myThreadTcpClient.Start();
myThreadUdpMonitor.Start();
myThreadHandler.Start();
// Just change your main window's load to hide itself... windowStateChange("Hide");
Application.Run(mainAnnounceWindow);
}