我的XAML中有一个please wait TextBlock,它的Visibility属性绑定到了ViewModel (实现INotifyPropertyChanged)上的IsBusy属性。一个单独的按钮启动一个长时间运行的进程(2-3秒),如下所示:
IsBusy = true;
try
{
// Do some long-running process
}
finally
{
IsBusy = false;
}但是please wait消息从未出现过。我假设操作在UI线程上运行,因此没有给它一个刷新的机会?如果我在一个单独的线程上运行上面的代码,它确实有效,但是我不希望用户在运行操作时做任何事情--我很高兴UI到freeze。
如何显示please wait消息?或者我会更好地在后台线程上运行它,并(以某种方式)锁定UI的持续时间吗?我使用的是.Net 4。
发布于 2013-01-30 16:35:06
您是正确的,它没有更新,因为您在同一个线程上运行代码,所以在进程完成后才会继续呈现。
您说您不使用后台线程,因为您不希望用户在运行操作时执行任何操作,但是像这样完全锁定应用程序绝不是一个好主意。
更好的解决方案是将窗体/ IsEnabled /UserControl/etc的IsBusy绑定到IsBusy属性。然后,当它变得繁忙时,整个表单将被禁用,以防止用户修改它,同时不锁定您的应用程序。
发布于 2013-01-30 15:37:31
首先,Visibility属性不是bool,所以如果您想将bool变量绑定到它,您需要使用IValueConverter,其次,是的,您是对的,当UI线程忙于长期运行的操作时,它将不会执行任何其他的操作,包括可见性更改。
我建议使用WPF Toolkit BusyIndicator expect来放置您自己的面板,它具有IsBusy bool属性。
另外,froozen用户界面对用户不友好,通常我使用以下代码片段
IsBusy = true;
Task.Factory.StartNew(() =>
{
// Do work.
})
.ContinueWith(t=>IsBusy=false,
TaskScheduler.FromCurrentSynchronizationContext());还请注意检查ContinueWith方法中的错误,否则将在Task dispose上获得异常。
发布于 2013-01-30 15:40:27
如果在单独的线程上运行代码,仍然可以通过Dispatcher.BeginInvoke Method访问UI。
if (!YOURCONTROL.Dispatcher.CheckAccess())
{
YOURCONTROL.Dispatcher.Invoke(System.Windows.Threading.DispatcherPriority.Normal,
new Action(delegate()
{
//do something with the control/form/...
}));
}
else
{
//update your control
}https://stackoverflow.com/questions/14607586
复制相似问题