1
0
Files
cpo-lab/ProgressBar/ProgressBarWindow.xaml.cs
2024-09-11 20:21:01 +03:00

135 lines
4.4 KiB
C#

using System;
using System.ComponentModel;
using System.Windows;
namespace ProgressWindow;
/// <summary>
/// Interaction logic for ProgressBar.xaml
/// </summary>
public partial class ProgressBarWindow : Window
{
/// <summary>
/// Событие, вызываемое при отмене задачи.
/// </summary>
public event EventHandler? Cancelled;
/// <summary>
/// Объект для синхронизации доступа к переменным.
/// </summary>
private readonly object _lock = new();
/// <summary>
/// Флаг, указывающий, нужно ли автоматически закрывать окно по завершении задачи.
/// </summary>
private readonly bool _autoClose;
/// <summary>
/// Максимальное значение прогресса.
/// </summary>
private readonly int _maxProgress;
/// <summary>
/// Текущее значение прогресса.
/// </summary>
private int _progress = 0;
/// <summary>
/// Флаг, указывающий, была ли задача отменена.
/// </summary>
private bool _isCancelled = false;
/// <summary>
/// Флаг, указывающий, завершена ли задача.
/// </summary>
private bool _isCompleted = false;
/// <summary>
/// Конструктор для инициализации окна прогресса.
/// </summary>
/// <param name="parTitle">Заголовок окна.</param>
/// <param name="parInitialMessage">Начальное сообщение для отображения.</param>
/// <param name="parMaxProgress">Максимальное значение прогресса.</param>
/// <param name="parAutoClose">Флаг, указывающий, должно ли окно закрываться автоматически по завершении.</param>
public ProgressBarWindow(string parTitle, string parInitialMessage, int parMaxProgress, bool parAutoClose = true)
{
InitializeComponent();
Title = parTitle;
_messageTextBlock.Text = parInitialMessage;
_maxProgress = parMaxProgress;
_autoClose = parAutoClose;
}
/// <summary>
/// Увеличивает текущий прогресс на указанную величину и обновляет сообщение, если предоставлено.
/// </summary>
/// <param name="parIncrement">Количество единиц, на которое нужно увеличить прогресс.</param>
/// <param name="parMessage">Сообщение для отображения в окне (опционально).</param>
/// <returns>Возвращает true, если задача была отменена.</returns>
public bool AdvanceProgress(int parIncrement = 1, string? parMessage = null)
{
lock (_lock)
{
_progress += parIncrement;
if (_progress >= _maxProgress)
{
_progress = _maxProgress;
_isCompleted = true;
_cancelButton.Content = "Close";
}
if (parMessage != null)
_messageTextBlock.Text = parMessage;
_progressBar.Value = (double)_progress / (double)_maxProgress * 100;
_progressBar.ToolTip = $"{_progress}/{_maxProgress} {parMessage}";
if (_isCompleted && _autoClose)
Close();
}
return _isCancelled;
}
/// <summary>
/// Обработчик события закрытия окна.
/// </summary>
/// <param name="parSender">Источник события.</param>
/// <param name="parE">Аргументы события закрытия окна.</param>
private void Window_Closing(object parSender, CancelEventArgs parE)
{
if (_isCompleted)
return;
if (!_isCancelled)
Cancel();
}
/// <summary>
/// Обработчик события нажатия на кнопку "Cancel/Close".
/// </summary>
/// <param name="parSender">Источник события.</param>
/// <param name="parE">Аргументы события.</param>
private void CancelButton_Click(object parSender, RoutedEventArgs parE)
{
if (!_isCompleted)
Cancel();
Close();
}
/// <summary>
/// Выполняет отмену задачи и отключает кнопку отмены.
/// </summary>
private void Cancel()
{
if (_isCancelled)
return;
_cancelButton.IsEnabled = false;
_isCancelled = true;
Cancelled?.Invoke(this, EventArgs.Empty);
}
}