2014-12-29 53 views
1

我想改變使用C#的WPF按鈕的顏色。WPF屬性沒有立即反映(只反映最後的變化)

比方說,我有一個WPF按鈕,我想改變爲1秒,其顏色:

<Button Name="Button1"></Button> 

我也有一個按鈕,用於啓動一個變化:

<Button Name="ProcessControl" Click="ProcessControl_Click">Start</Button> 

我有C#代碼不作任何可見的變化:

private void ProcessControl_Click(object sender, RoutedEventArgs e) 
{ 
     Brush background = button.Background; 
     Button1.Background = System.Windows.Media.Brushes.Yellow; 
     Thread.Sleep(1000); 
     Button1.Background = background; 
} 

但是,如果我會寫這個代碼,哪個cha nges顏色,不等待第二個,它不會恢復舊的顏色,它的工作原理:

private void ProcessControl_Click(object sender, RoutedEventArgs e) 
{ 
     Brush background = button.Background; 
     Button1.Background = System.Windows.Media.Brushes.Yellow; 
} 

這是一個與所有WPF元素和屬性同樣的事情。如果某些屬性發生了兩次更改,只有最後一次更改纔會反映出來

我也試着撥打:

this.UpdateLayout(); 

,但它不解決問題。

我試過使用後臺工作,但它也不能解決我的問題。

現在是否有人如何立即反映使用C#的WPF中的屬性更改?

+1

這很可能是你的'線程。睡眠(1000)'會阻塞UI線程,因此按鈕不會以新顏色重新繪製。你應該使用動畫來代替http://msdn.microsoft.com/en-us/library/ms752312%28v=vs.110%29.aspx –

回答

2

問題是您用Sleep阻止UI線程,這意味着無法呈現更新的屬性。如果你使用的是支持異步版本/的await,可以轉而嘗試這個辦法:

private async void ProcessControl_Click(object sender, RoutedEventArgs e) 
{ 
     Brush background = button.Background; 
     Button1.Background = System.Windows.Media.Brushes.Yellow; 
     await Task.Delay(1000); 
     Button1.Background = background; 
} 

這在UI線程上註冊一個回調後一秒火(假設Click事件處理程序從UI叫除非手動調用該方法,否則它應該始終保持)。

+0

使用'await'就像這樣感覺*錯誤*。它當然有用;好答案! – BradleyDotNET

+0

@BradleyDotNET,我喜歡使用'Task.Delay'作爲在UI線程上註冊一個定時器回調的簡短版本;我現在幾乎總是用這個代替明確的定時器。當然,擁有異步無效的方法並不是一個很好的做法;當你將上面的模式概括爲生產代碼時,你肯定必須留意在假設的情況下可能會改變你的應用程序狀態(在睡眠UI線程時通常會被抑制)。這些相同的問題,雖然也許在等待時不那麼明顯。 –

0

第一個代碼示例將不起作用,因爲您用Thread.Sleep阻止了UI線程。基本上,你(在UI線程)

  1. 改變顏色
  2. 睡眠(注意UI一直沒有機會尚未更新!)
  3. 更改顏色重新
  4. UI更新,到舊的顏色!

在後臺工作人員這樣做可工作如果你改變了顏色,然後睡在另一個線程的第二個變化。當然,這個改變將不得不被封送回UI線程,所以如果你不小心在Sleep的位置,你會看到相同的行爲。

實際上,你應該改變顏色,然後設置一個計時器。在該計時器的Elapsed事件中,將顏色設回。您也可以使用async/await,以便UI線程不會阻塞,就像Dan Bryant的回答一樣。