2013-07-08 24 views
0

我有這樣的事情:IsEnabled = false; //不會 「立竿見影」

void ClickHandler() // Called from several places 
{ // Try to prevent queuing accidental extra clicks during lengthy operation 
    GetMainWindow().IsEnabled = false; // "GetMainWindow()" you know what I mean 
    DoLengthyStuffInThisThread(); // Yes, I know I shouldnt 
    PresentResult(); 
    GetMainWindow().IsEnabled = true; 
} 

,基本上就是這樣。澄清雖然:

即使我已經設置IsEnabled = false它沒有所需的效果,我的額外點擊經歷在操作過程中。 (如果我回到而不恢復的價值它不會有效果。)我認爲通常我線程需要以回報爲禁止向有效果,但我寧可不創建一個額外的線程。

+2

由於您正在UI線程上進行處理,因此在ClickHandler完成之前UI不會更新。在完成時,該值是真實的。 – Paparazzi

+2

從長遠來看,它會減少*爲你工作,正確地做到這一點。試圖通過做錯誤來節省時間就像走到城鎮的另一邊,因爲進入你的車是太多的工作。 – Servy

+0

@Servy - 不了了之以後誰做它「快速和骯髒」的方式咒罵你的名字同事的說。 –

回答

0

謝謝大家回答。最好的答案竟是的* 意見一一,由威爾Eddins。特別感謝! *

的uggly回答我uggly的問題是:System.Windows.Forms.Application.DoEvents();

慘不忍睹,但是這是我必須做的。孩子們,不要在家裏試試這個!

public void WrapLengthyWork(Action lengthyWork) 
    { 
     SetWaiting(true); 
     System.Windows.Forms.Application.DoEvents(); 
     lengthy(); 
     SetWaiting(false); 
    } 

    public void SetWaiting(bool wait) 
    { 
     if (wait == true) 
     { 
      Mouse.OverrideCursor = Cursors.Wait; 
      Application.Current.MainWindow.IsEnabled = false; 
     } 
     else 
     { 
      IsEnabled = true; 
      Mouse.OverrideCursor = Cursors.Arrow; 
     } 
    } 

而且,所有的你,建議我做正確,與線程切換:感謝你。我(正如我所提到的)痛苦地意識到上面的代碼片段是糟糕的編碼風格。我的問題是,「LengthyWork()」本身就是百病用的東西,參考回到GUI,必須在GUI線程中運行,如:

while(stuffToDo) 
{ 
    Fetch(); 
    Calculate(); 
    UpdateGUI(); 
} 

鑑於強加時間限制(幾個小時),有限的任務(「防止加工過程中的點擊和顯示等待光標和觸摸沒有別的」)妥善解決不幸不是一種選擇。

+1

所以我就在這裏。在不幸的情況下被迫採用不幸的解決方案。我爲這一切的醜陋道歉。並且仍然被踢。沒有評論。 – Adam

+0

感謝您發佈這篇文章,儘管它的評價很低,但有時需要在需要時發生,尤其是在您沒有完全控制的代碼的情況下。只是因爲他們沒有遇到他們需要的情況,並不意味着它應該「永遠不會」被使用。 – Josh

+0

當你工作的項目中,你沒有像每個人似乎認爲其他人都已經完成的代碼一樣多的控制時,這會有奇效。許多人不知道有時候有些事情必須以「醜陋」的方式來完成,因爲實際上沒有別的辦法可以與你一起工作。這個DoEvents方法在一兩次之內就成爲了救星。 – Josh

2

您必須將冗長的工作卸載到另一個線程。在封閉方法完成後,用戶界面不會收到有關此更改的通知(因此,沒有機會使用佈局傳遞刷新它的狀態)。

我會想象在冗長的方法裏面發生的任何事情是操縱UI上顯示的一些數據。如果您使用數據綁定,此操作將填充在後臺UI(如果它在後臺線程上運行),然後當操作完成,它可以告訴UI重新啓用自己。

這是半僞代碼,但請查看Task.Factory.StartNew和Dispatcher.BeginInvoke。

public void ClickHandler() 
    { 
     MainWindow.IsEnabled = false; 

     Task.Factory.StartNew(() => 
      { 
       // Length work goes here 
      }).ContinueWith((result) => 
       { 
        Dispatcher.BeginInvoke(() => 
         { 
          MainWindow.IsEnabled = true; 
         }); 
       }); 
    } 
+1

那麼,當他做出改變時,UI *會被改變,問題是在方法結束之前什麼也不能做;該「其他」包括重畫屏幕的相關部分,響應點擊/鍵盤事件等等。儘管最終結果基本上是正確的,但稍微改變了措辭。 – Servy

+0

感謝威廉。這本來不錯,但是讓我們留下的力量與VS2008保持一致。所以沒有花俏的.NET 4的東西。但無論如何,線程的事情在我自己的答案中看到了...... – Adam

相關問題