Не выполняя весь процесс для вас, вы можете создать окно, которое открывается поверх активного окна с панелью прогресса на нем, а затем отправить прогресс на него с событием.
Я только что создал этот индикатор выполнения:
<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>
и модель вида выглядит так:
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();
}
}
}
Событие выглядит
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);
}
}
}
И App.xaml.cs выглядит так:
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();
}
}
Затем я создал кнопку в MainWindow, у которой есть и обработчик событий, который выглядит так:
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();
});
}
В принципе, это откроет окно индикатора выполнения и закроет его, когда это будет сделано. Вам нужно будет выяснить, как позиционировать прогресс над окном, на котором вы хотите запустить прогресс.