簡體   English   中英

嘗試在長時間運行的操作中在WPF中顯示“請稍候”消息

[英]Trying to display a “please wait” message in WPF during a long-running operation

我在XAML中有一個TextBlockplease wait ,其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 btw。

您是正確的,它不會更新,因為您是在同一線程上運行代碼,因此直到過程完成后才繼續渲染。

您說您不使用后台線程是因為您不希望用戶在操作運行時執行任何操作,但是完全鎖定這樣的應用程序從來不是一個好主意。

更好的解決方案是將Form / Window / UserControl / etc的IsEnabled綁定到IsBusy屬性。 然后,當它變得繁忙時,整個表單將被禁用,以防止用戶修改它,而不會鎖定您的應用程序。

首先, Visibility屬性不是bool ,因此,如果要將bool變量綁定到它,則需要使用IValueConverter ,其次,是的,您是對的,而UI線程正忙於長時間運行的操作,它將不執行任何其他操作,包括可見性更改。

我建議使用WPF Toolkit BusyIndicator期望放置自己的面板,它具有IsBusy bool屬性。

另外froozen UI不是用戶友好的,通常我使用此代碼段

IsBusy = true;
Task.Factory.StartNew(() => 
{ 
  // Do work. 
})
.ContinueWith(t=>IsBusy=false, 
                        TaskScheduler.FromCurrentSynchronizationContext());

另請注意檢查ContinueWith方法中的錯誤,否則您將在Task Dispose上獲得異常

如果在單獨的線程上運行代碼,仍然可以通過Dispatcher.BeginInvoke方法訪問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
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM