一种简单的方法是使用忙碌指示器 扩展的WPF工具包 :
下载二进制文件并将项目引用添加到WPFToolkit.Extended.dll。
接下来在“主窗口”中添加以下命名空间:
xmlns:ext="clr-namespace:Microsoft.Windows.Controls;assembly=WPFToolkit.Extended"
然后在视图中添加忙指示符(放置它以便在显示时占用整个屏幕)这里我的主窗口有两行,我希望控件跨越两行。控件的IsBusy属性绑定到视图数据上下文中的bool属性。
<ext:BusyIndicator Grid.RowSpan="2" x:Name="busyIndicator" IsBusy="{Binding IsBusy}" />
应该在另一个线程中处理持久计算,以便它不会阻止用户界面。对于线程,您可以使用 BackgroundWorker类 。
您应该在单独的线程中执行长时间运行的任务以避免UI阻塞。 这是你可以实现的一种方式:
定义后台线程如下:
//Delegate that you could pass into the worker thread public delegate void ProgressMonitor(string s); //Call this to start background work void StartLongRunningWork(ProgressMonitor mon) { using (BackgroundWorker bgw = new BackgroundWorker()) { bgw.DoWork += WorkerThread; bgw.RunWorkerCompleted += WorkerThreadCompleted; bgw.RunWorkerAsync(mon); } } void WorkerThread(object sender, DoWorkEventArgs e) { ProgressMonitor pm = (ProgressMonitor)e.Argument; WorkerActual(pm, <any other parameters>); } void WorkerActual(ProgressMonitor pm,<any other parameters>) { ... pm("Doing x"); Do long running task pm("Doing y"); ... } //This function is called in case of Exception, Cancellation or successful completion //of the background worker. Handle each event appropriately void WorkerThreadCompleted(object sender, RunWorkerCompletedEventArgs e) { if (e.Error != null) { //Long running task threw an exception } else if (e.Cancelled) { //Long running task was cancelled } else { //Long running task was successfuly completed } }
并将其命名如下:
private void UpDateProgressLabel(string s) { this.Dispatcher.BeginInvoke((Action)delegate { NotificationLabel.Content = s; }); } private void Button_Click(object sender, RoutedEventArgs e) { StartLongRunningWork(UpDateProgressLabel); }