2016-10-03 83 views
0

長時間操作時,我想禁用按鈕並清除文本塊。長時間操作時禁用按鈕

在按鈕點擊畫的屏幕使按鍵永不明顯禁用

private bool btnEnabled = true; 
public bool BtnEnabled 
{ 
    get { return btnEnabled; } 
    set 
    { 
     if (value == btnEnabled) 
      return; 
     btnEnabled = value; 
     NotifyPropertyChanged("BtnEnabled"); 
    } 
} 
private string results = "start"; 
public string Results 
{ 
    get { return results; } 
    set 
    { 
     if (value == results) 
      return; 
     results = value; 
     NotifyPropertyChanged("Results"); 
    } 
} 

private void btn_Click(object sender, RoutedEventArgs e) 
{ 
    BtnEnabled = false; 
    Results = string.Empty; 
    // whould like to displany wait spinner 
    LongProcess(); 
    BtnEnabled = true; 
} 
private void LongProcess() 
{ 
    //database query 
    System.Threading.Thread.Sleep(10000); 
    Results = "this is the results"; 
} 

如何獲得的按鈕長事件期間禁用前的事件完全處理的?

問題我有是用戶感到沮喪,並開始點擊和這些點擊都在隊列中並得到處理。

+0

使用後臺處理運行長碼。這將允許UI線程更新並顯示更改以禁用按鈕。 – crashmstr

+1

我認爲你可以嘗試異步&等待實現這一點。 – ViVi

+0

@Rennie是等待似乎要訣竅 – Paparazzi

回答

-1

這是我結束了

private async void btn_Click(object sender, RoutedEventArgs e) 
{ 

    BtnEnabled = false; 
    Results = string.Empty; 
    // whould like to displany wait spinner 
    //LongProcess(); 
    cts = new CancellationTokenSource(); 
    try 
    { 
     //cts.Cancel(); just for test 
     string result = await WaitAsynchronouslyAsync(cts.Token); 
     //string result = await WaitSynchronously(); 

     BtnEnabled = true; 
     Results = result; 
    } 
    catch (OperationCanceledException) 
    { 
     Results = "Operation canceled"; // this is not called 
    } 
    cts = null; 
} 
// The following method runs asynchronously. The UI thread is not 
// blocked during the delay. You can move or resize the Form1 window 
// while Task.Delay is running. 
public async Task<string> WaitAsynchronouslyAsync(CancellationToken ct) 
{ 
    //DataBaseQuery(); // this just runs async 
    //SqlCommand cmd = new SqlCommand(); 
    //await cmd.ExecuteScalarAsync(ct); 
    await Task.Delay(10000); 
    return "Finished"; 
} 
0

爲了回答您的具體問題,你可以使用這樣的事情,使UI過程中的消息(在設置按鈕禁用):

Application.Current.Dispatcher.Invoke(
      DispatcherPriority.Background, 
      new Action(delegate { }) 
      ); 

還是較爲齊全:

public void DoEvents() 
{ 
    DispatcherFrame frame = new DispatcherFrame(); 
    Dispatcher.CurrentDispatcher.BeginInvoke(DispatcherPriority.Background, 
     new DispatcherOperationCallback(ExitFrame), frame); 
    Dispatcher.PushFrame(frame); 
} 

public object ExitFrame(object f) 
{ 
    ((DispatcherFrame)f).Continue = false; 
    return null; 
} 

再次,這不建議(它相當於Winforms上使用Application.DoEvents(),它有許多警告,應該像瘟疫一樣避免,除非你知道你在做什麼)。長時間的密集操作不應該在UI線程上完成,或者如果CPU密集度不高,則可以使用async/await

+0

長時間的操作是等待數據庫查詢 – Paparazzi

+0

您可以使用異步/等待它:但是,然後再次,這將是一個不同的答案,這將不符合您提出的問題 – Jcl

+0

更好地禁用按鈕(或事件整個窗口),顯示一個遊標或其他加載UI元素,然後在一個單獨的線程中執行緩慢的過程。當thead結束時,使用Dispatcher.Invoke在UI線程上使用你的窗口(... – apc