using System;
using System.ComponentModel;
using System.Linq;
using System.Threading;
using System.Windows.Media.Imaging;
namespace InABox.WPF
{
public class ProgressSection
{
public ProgressSection(string message, Action action)
{
Message = message;
Action = action;
}
public string Message { get; set; }
public Action Action { get; set; }
}
public static class Progress
{
private static ProgressForm? form;
public static BitmapImage? DisplayImage { get; set; }
public static bool IsVisible => form != null;
public static void ShowModal(params ProgressSection[] sections)
{
if (!sections.Any())
return;
var progress = new ProgressForm
{
DisplayImage = DisplayImage
};
progress.Activated += (_, args) =>
{
progress.Dispatcher.Invoke(() =>
{
foreach (var section in sections)
{
progress.Progress.Content = section.Message;
section.Action();
}
progress.Close();
});
};
progress.ShowActivated = true;
progress.ShowDialog();
}
///
/// Shows progress dialog modally, with a cancel button.
///
///
///
///
/// Whether the progress was completed without cancelling.
public static bool ShowModal(string message, string cancelButtonText, Action, CancellationToken> work)
{
var cancellationTokenSource = new CancellationTokenSource();
var progress = new ProgressForm(cancelButtonText)
{
DisplayImage = DisplayImage
};
progress.Progress.Content = message;
progress.Loaded += (_, args) =>
{
var worker = new BackgroundWorker();
var update = new Progress(data => progress.Progress.Content = data);
progress.OnCancelled += () =>
{
cancellationTokenSource.Cancel();
progress.Close();
};
worker.DoWork += (o, e) => work(update, cancellationTokenSource.Token);
worker.RunWorkerCompleted +=
(o, e) => progress.Close();
worker.RunWorkerAsync();
};
progress.ShowDialog();
return !cancellationTokenSource.IsCancellationRequested;
}
public static void ShowModal(string message, Action> work)
{
Exception? exception = null;
var progress = new ProgressForm
{
DisplayImage = DisplayImage
};
progress.Progress.Content = message;
progress.Loaded += (_, args) =>
{
var worker = new BackgroundWorker();
var update = new Progress(data => progress.Progress.Content = data);
progress.OnCancelled += () =>
{
worker.CancelAsync();
};
worker.DoWork += (o, e) =>
{
try
{
work(update);
}
catch (Exception ex)
{
exception = ex;
}
};
worker.RunWorkerCompleted +=
(o, e) => progress.Close();
worker.RunWorkerAsync();
};
progress.ShowDialog();
if(exception is not null)
{
throw exception;
}
}
public static void Show(string message)
{
if (form == null)
{
form = new ProgressForm
{
DisplayImage = DisplayImage
};
form.Show();
}
form.UpdateWindow(message);
}
public static void SetMessage(string message)
{
form?.UpdateWindow(message);
}
public static void Close()
{
form?.CloseWindow();
form = null;
}
}
}