Without doing the entire process for you, You could create a window that that opens on top of the active window with a progressbar on it then send the progress to it with an event.
I Just created this progress bar:
<Window x:Class="ProgressBar.Views.ProgressBar"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d"
WindowStyle="None"
Title="ProgressBar" Height="25" Width="250">
<Grid VerticalAlignment="Center">
<ProgressBar Minimum="0" Maximum="100" Height="25" Value="{Binding Progress}"></ProgressBar>
</Grid>
and the view model looks like :
public class ProgressViewModel:INotifyPropertyChanged
{
private int _progress;
public event PropertyChangedEventHandler PropertyChanged;
[NotifyPropertyChangedInvocator]
protected virtual void OnPropertyChanged([CallerMemberName] string propertyName = null)
{
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
}
public ProgressViewModel()
{
ProgressBarEvent.GetInstance().ProgressChanged += (s, e) => Application.Current.Dispatcher.Invoke(()=> Progress = e);
}
public int Progress
{
get => _progress;
set
{
_progress = value;
OnPropertyChanged();
}
}
}
the Event looks like
public class ProgressBarEvent
{
private static ProgressBarEvent _instance;
public static ProgressBarEvent GetInstance()
{
if(_instance == null)
_instance = new ProgressBarEvent();
return _instance;
}
public EventHandler<int> ProgressChanged;
public EventHandler Show;
public EventHandler Close;
public ProgressBarEvent Start()
{
OnShow();
return this;
}
public ProgressBarEvent Stop()
{
OnStop();
return this;
}
private void OnShow()
{
if (Show is EventHandler show)
{
show.Invoke(this, new EventArgs());
}
}
private void OnStop()
{
if (Close is EventHandler close)
{
close.Invoke(this, new EventArgs());
}
}
public void SendProgress(int progress)
{
if (ProgressChanged is EventHandler<int> progressChanged)
{
progressChanged.Invoke(this, progress);
}
}
}
And the App.xaml.cs looks like:
public partial class App : Application
{
protected override void OnStartup(StartupEventArgs e)
{
base.OnStartup(e);
ProgressBarEvent.GetInstance().Show += ShowProgressBar;
ProgressBarEvent.GetInstance().Close += CloseProgressBar;
}
private Views.ProgressBar progressBarWindow;
private void CloseProgressBar(object sender, EventArgs e)
{
Application.Current.Dispatcher.Invoke(() => progressBarWindow.Close());
}
private void ShowProgressBar(object sender, EventArgs e)
{
progressBarWindow = new Views.ProgressBar();
var activeWindow = Application.Current.Windows.OfType<Window>().FirstOrDefault(x => x.IsActive);
progressBarWindow.Owner = activeWindow;
progressBarWindow.Show();
}
}
Then i created a Button on the MainWindow that has and event handler that looks like:
private async void ButtonBase_OnClick(object sender, RoutedEventArgs e)
{
ProgressBarEvent.GetInstance().Start();
await Task.Run(() =>
{
for (int i = 0; i < 100; i++)
{
ProgressBarEvent.GetInstance().SendProgress(i);
Thread.Sleep(100);
}
ProgressBarEvent.GetInstance().Stop();
});
}
Basically, this will open the progress bar window and close it when it Is done. You will have to figure out how to position the progress over the window that you want to run the progress on.