首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >试图在长期运行的操作中在WPF中显示“请等待”消息。

试图在长期运行的操作中在WPF中显示“请等待”消息。
EN

Stack Overflow用户
提问于 2013-01-30 15:29:21
回答 3查看 3.9K关注 0票数 4

我的XAML中有一个please wait TextBlock,它的Visibility属性绑定到了ViewModel (实现INotifyPropertyChanged)上的IsBusy属性。一个单独的按钮启动一个长时间运行的进程(2-3秒),如下所示:

代码语言:javascript
复制
IsBusy = true;

try
{
    // Do some long-running process
}

finally
{
    IsBusy = false;
}

但是please wait消息从未出现过。我假设操作在UI线程上运行,因此没有给它一个刷新的机会?如果我在一个单独的线程上运行上面的代码,它确实有效,但是我不希望用户在运行操作时做任何事情--我很高兴UI到freeze

如何显示please wait消息?或者我会更好地在后台线程上运行它,并(以某种方式)锁定UI的持续时间吗?我使用的是.Net 4。

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2013-01-30 16:35:06

您是正确的,它没有更新,因为您在同一个线程上运行代码,所以在进程完成后才会继续呈现。

您说您不使用后台线程,因为您不希望用户在运行操作时执行任何操作,但是像这样完全锁定应用程序绝不是一个好主意。

更好的解决方案是将窗体/ IsEnabled /UserControl/etc的IsBusy绑定到IsBusy属性。然后,当它变得繁忙时,整个表单将被禁用,以防止用户修改它,同时不锁定您的应用程序。

票数 5
EN

Stack Overflow用户

发布于 2013-01-30 15:37:31

首先,Visibility属性不是bool,所以如果您想将bool变量绑定到它,您需要使用IValueConverter,其次,是的,您是对的,当UI线程忙于长期运行的操作时,它将不会执行任何其他的操作,包括可见性更改。

我建议使用WPF Toolkit BusyIndicator expect来放置您自己的面板,它具有IsBusy bool属性。

另外,froozen用户界面对用户不友好,通常我使用以下代码片段

代码语言:javascript
复制
IsBusy = true;
Task.Factory.StartNew(() => 
{ 
  // Do work. 
})
.ContinueWith(t=>IsBusy=false, 
                        TaskScheduler.FromCurrentSynchronizationContext());

还请注意检查ContinueWith方法中的错误,否则将在Task dispose上获得异常。

票数 1
EN

Stack Overflow用户

发布于 2013-01-30 15:40:27

如果在单独的线程上运行代码,仍然可以通过Dispatcher.BeginInvoke Method访问UI。

代码语言:javascript
复制
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
}
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/14607586

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档