I have a wpf application which does very heavy actions in which the user needs to wait while the application "thinks".
What I want to do is, while the main thread of the application is thinking, another thread will disable the whole window and give it kind of a grayish color and a circular progress bar will appear in the middle of the screen.
It's kind of a big question and I don't really need the whole code to do this just the general Idea.
Thanks for all your help..
In addition to the above suggestions (Background worker, Dispatcher) - yes these are the correct techniques to get what you want, but let me discuss the UI effect you requested in your question. If you are using the MVVM pattern, you can create some "I'm busy" UI and bind to an IsBusy property in the view model to show and hide the UI. For instance:
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;
}
}
}
Then in the UI use this xaml (or similar)
<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>
The net effect will be when you use a background worker or threadpool to call the DoLongRunningOperation function in your viewmodel, the border defined in Xaml will show/hide as the operation starts/stops. You won't need the dispatcher to invoke here either as WPF handles the thread marshalling for you.
There are implementations of busy controls with whirlygig animations etc... on the net too to spice up the UI.
Best regards,
Use Dispatcher.BeginInvoke to change the Enable-Property of the UI components and show/hide the progressbar out of the worker thread
for the worker-thread you can use the BackgroundWorker-Class
Offload the heavy action to a new thread and do the UI stuff (disable, gray out and progress bar) on the main thread. See BackgroundWorker and Dispatcher.
Using a new thread for the UI stuff is possible, but not using the existing Window. A UI control (Dispatcher) can online be used/called by the thread it belongs to. You could however create a new thread and use a new Window with a new Dispatcher to do the UI stuff. You would then have to position the new Window over the original. Not as easy as my first suggestion. It might be an option if you don't know when the heavy action is executed. See here, here and here.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With