我有一个wpf应用程序,它执行非常繁重的操作,用户在应用程序“认为”时需要等待。“繁忙”效果覆盖
我想要做的是,当应用程序的主线程正在考虑时,另一个线程将禁用整个窗口,并给它一种灰色的颜色,并在屏幕中间出现一个圆形的进度条。
这是一个很大的问题,我并不需要整个代码来做这个只是一般的想法。
感谢您的帮助..
我有一个wpf应用程序,它执行非常繁重的操作,用户在应用程序“认为”时需要等待。“繁忙”效果覆盖
我想要做的是,当应用程序的主线程正在考虑时,另一个线程将禁用整个窗口,并给它一种灰色的颜色,并在屏幕中间出现一个圆形的进度条。
这是一个很大的问题,我并不需要整个代码来做这个只是一般的想法。
感谢您的帮助..
卸载重行动,以一个新的线程,做在主线程的UI的东西(禁用,灰色出来,进度条)。请参阅BackgroundWorker and Dispatcher。
使用一个新的线程为UI的东西是可能的,但不使用现有的窗口。一个UI控件(Dispatcher)可以在线使用/调用它所属的线程。然而,你可以创建一个新的线程,并使用一个新的窗口与一个新的分派器来做UI的东西。然后您必须将新窗口置于原始位置。不像我的第一个建议那么容易。如果您不知道重执行何时执行,那么这可能是一个选项。见here,here和here。
使用Dispatcher.BeginInvoke改变启用,物业的UI组件,并显示/隐藏进度进行辅助线程
的工作线程,你可以使用BackgroundWorker-Class
非常感谢,这非常有帮助! – 2012-01-03 12:23:26
看看这个示例:
public void DoHeavyWork()
{
mainDispatcher = Dispatcher.CurrentDispatcher;
DisableWindow();
workDelegate.BeginInvoke(EnableWindowCallBack, null);
}
private void EnableWindowCallBack(IAsyncResult asyncResult)
{
workDelegate.EndInvoke(asyncResult);
mainDispatcher.InvokeIfRequired(() => { EnableWindow(); });
}
当你调用DoHeavyWork
我认为我们是可以访问的用户界面,这应该是平常的线程上。 DisableWindow
显示动画或任何工作时应显示的内容。然后调用预定义的代理,workDelegate
将在新线程上运行,并且完成后,回调应恢复该视图。
请注意,EnableWindow
的调用必须在有权访问UI的线程上进行。
非常感谢,这非常有帮助! – 2012-01-03 12:36:32
很高兴能有所帮助。您可以通过投票表明您的感谢,并接受其中一个答案作为正确答案。 – 2012-01-31 18:21:59
除了上述建议(后台工作人员,调度员) - 是的,这些是获得你想要的正确技术,但让我讨论你在你的问题中请求的UI效果。如果您使用的是MVVM模式,则可以创建一些“我很忙”的UI并绑定到视图模型中的IsBusy属性以显示和隐藏UI。例如:
public class MyViewModel : INotifyPropertyChanged
{
// Bind to this property any UI you want to
// show/hide during long running updates
public bool IsBusy
{
get { return _isBusy; }
set
{
_isBusy = true;
OnPropertyChanged("IsBusy");
}
}
private void OnPropertyChanged(string prop)
{
var handler = PropertyChanged;
if (handler != null)
{
handler(this, new PropertyChangedEventArgs(prop));
}
}
// Note: This is intended to be called on a background thread
private void DoLongRunningOperationOnABackgroundThread()
{
try
{
IsBusy = true;
// do your work
}
finally
{
IsBusy = false;
}
}
}
然后在UI使用此XAML(或类似)
<UserControl:MyControl x:Class="MyApp.MyControl"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
<UserControl.Resources>
<BooleanToVisibilityConverter x:Key="boolToVis"/>
</UserControl.Resources>
<Grid>
<!-- your UI code goes here -->
<!-- Below this, at higher Z-Order place a control to gray out the screen when IsBusy = true -->
<Border Background="#55000000" BorderThickness="0" Visibility="{Binding IsBusy, Converter={StaticResource boolToVis}}">
<TextBlock Text="I AM BUSY!" Font-Size="32" VerticalAlignment="Center" HorizontalAlignment="Center" Foreground="White"/>
</Border>
<Grid>
</UserControl>
当你使用一个后台工作或线程池来调用DoLongRunningOperation功能在您的视图模型的净效应将是, Xaml中定义的边界会在操作开始/停止时显示/隐藏。当WPF为你处理线程编组时,你不需要调度器在这里调用。
在网上也有一些带有旋转动画等的繁忙控件的实现,它们也不适合用户界面。
最好的问候,
谢谢,我在网上发现了一些很酷的动画实现,谢谢了很多 – 2012-01-03 12:24:21
没有probs :)请注意,您可以使用WPF Grid将控件直接放在另一个控件上(Z指数更高)。这对于您正在寻找的灰色效果非常有用。 – 2012-01-03 12:31:29
非常感谢你,这是非常有益的! – 2012-01-03 12:23:34