簡體   English   中英

標簽文字顏色更改失敗

[英]Label text color change failed

labelStatus.Content = "Sending email... ";
labelStatus.Foreground = Brushes.Aqua;
Thread.Sleep(3000);
labelStatus.Foreground = Brushes.Pink;

為什么結果中沒有顯示Aqua顏色? 當代碼開始運行時它什么也不顯示,3 秒后文本直接顯示為Pink

使用Thread.sleep(3000)將凍結主線程。 相反,分配另一個線程在后台執行其他操作或使用async

你調用了Thread.Sleep(); 方法在將前景設置為Brushes.Aqua后立即執行,因此線程被凍結並且無法刷新控件。 然后當它在3000毫秒后最終解凍時,您再次將前景更改為Brushes.Pink

它應該在解凍后首先將標簽的前景渲染為Aqua ,然后渲染為Pink 但人們現在注意到還為時過早。

您可以在調用Thread.Sleep();之前強制線程刷新視圖Thread.Sleep(); 方法。 一個例子是來自這個答案DoEvents()方法的 WPF 版本。 或者,也許您可​​以嘗試使用BackgroundWorkerasync方法,但我沒有進行測試,因此不確定它是否可以正常工作。

Thread.Sleep(3000); 將凍結 GUI 線程。 此操作比 GUI 更改顏色的速度更快,因此即使代碼正確執行,您也不會看到它。 以下代碼應該可以解決您的問題:

BackgroundWorker worker = new BackgroundWorker();
labelStatus.Content = "Sending email...";
labelStatus.Foreground = Brushes.Aqua;
worker.DoWork += worker_DoWork;
worker.RunWorkerCompleted += worker_RunWorkerCompleted;
worker.RunWorkerAsync();

...

private void worker_DoWork(object sender, DoWorkEventArgs e)
{
    //Add logic here
    Thread.Sleep(3000);
}

private void worker_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
{
    labelStatus.Foreground = Brushes.Pink;
}

注意:我假設您有其他邏輯(例如發送電子郵件)需要代替Thread.Sleep(3000); . 您實際上需要強制掛起應用程序的情況非常少見。

使用Thread.Sleep是一個阻塞調用,這意味着 UI 線程被掛起,因此 UI 凍結。

暫停當前線程指定的時間量。

我猜你在按鈕事件處理程序中調用你的方法。 您可以做的是將async關鍵字添加到事件處理程序方法中,並將對Sleep的調用替換為Task.Delay並等待它。

private async void OnClick(object sender, RoutedEventArgs e)
{
   labelStatus.Content = "Sending email... ";
   labelStatus.Foreground = Brushes.Aqua;
   await Task.Delay(3000);
   labelStatus.Foreground = Brushes.Pink;
}

這樣,UI 線程不會被阻塞,並且在延遲到期后Foreground將設置為Pink

然而,這也不是正確的方法。 發送電子郵件或執行其他類型的操作可能會隨時間變化,因為帶寬、延遲或資源較少。 您不能也不應該依賴固定的時間跨度來等待並希望操作完成。 而是使用例如async/await模式使您的操作異步運行並在它真正完成時返回,就像上面的延遲一樣。 這將使您的 UI 保持響應,無論操作是提前還是延遲完成。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM