我有一個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