0

この投稿は、この特定のケースでは機能しないため、WinForms GUI C# をすばやく表示/非表示にする方法の続きです。

2 つの問題があります。

  • 1 は、mainAnnounceWindow GUI が非表示で開始し、後で呼び出されたときに windowStateChange("Show") で表示し、windowStateChange("Hide") で非表示にする必要があることです。アプリを起動すると、0.5秒ほど表示されるため、適切に機能しません(点滅しています)。非表示で開始し、0.5 秒間点滅しないようにする方法はありますか。

  • 2 は、windowStateChange が myThreadHandler (Queue.Work) から呼び出されたときに正しく機能しないことです。

    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 が正しく表示されません。私が間違っている何か。

ああ、もちろん私はいくつかカット/ペーストを行ったので、いくつかのものを見逃すかもしれません. 何かを追加する必要がある場合は、お知らせください。

よろしく、

イケナイ人

4

2 に答える 2

1

問題は、UI以外のスレッドからUIオブジェクトにアクセスしていることです。これは許可されていません。実行する操作をラップするデリゲートを、UIコントロールの1つ(おそらくフォームオブジェクト)のInvokeメソッドまたはBeginInvokeメソッドに渡す必要があります。

于 2010-02-03T18:14:35.490 に答える
1

問題は、これを追加したためにメインスレッドがロックされていることです。

while (true) { 
    Thread.Sleep(1000); 
} 

これにより、ウィンドウスレッドがウィンドウメッセージ(表示や非表示など)を適切に受信して処理できなくなります。

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);
}
于 2010-02-03T18:15:22.310 に答える