在长时间操作期间,我想禁用按钮并清除文本块。
在按钮上单击,在绘制屏幕之前完全处理事件,因此按钮永远不会被明显禁用
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 :(得分: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
。
答案 1 :(得分:-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";
}