134 lines
3.7 KiB
C#
134 lines
3.7 KiB
C#
using System;
|
|
using System.Windows;
|
|
using System.Windows.Media.Animation;
|
|
using System.Windows.Threading;
|
|
|
|
namespace 自救器呼吸器综合检验仪
|
|
{
|
|
public partial class LoadingOverlayWindow : Window
|
|
{
|
|
private static readonly TimeSpan MinimumDisplayDuration = TimeSpan.FromMilliseconds(700);
|
|
private static readonly TimeSpan DismissAnimationDuration = TimeSpan.FromMilliseconds(240);
|
|
|
|
private readonly DateTime _shownAtUtc;
|
|
private bool _closeRequested;
|
|
|
|
public LoadingOverlayWindow()
|
|
{
|
|
InitializeComponent();
|
|
_shownAtUtc = DateTime.UtcNow;
|
|
}
|
|
|
|
public void AlignTo(Window referenceWindow)
|
|
{
|
|
if (referenceWindow == null)
|
|
{
|
|
return;
|
|
}
|
|
|
|
WindowState = WindowState.Normal;
|
|
|
|
double width = referenceWindow.ActualWidth > 0 ? referenceWindow.ActualWidth : referenceWindow.Width;
|
|
double height = referenceWindow.ActualHeight > 0 ? referenceWindow.ActualHeight : referenceWindow.Height;
|
|
|
|
if (width <= 0 || height <= 0)
|
|
{
|
|
Rect restoreBounds = referenceWindow.RestoreBounds;
|
|
width = restoreBounds.Width > 0 ? restoreBounds.Width : width;
|
|
height = restoreBounds.Height > 0 ? restoreBounds.Height : height;
|
|
}
|
|
|
|
Left = referenceWindow.Left;
|
|
Top = referenceWindow.Top;
|
|
Width = width;
|
|
Height = height;
|
|
}
|
|
|
|
public void MatchTopmost(Window referenceWindow)
|
|
{
|
|
if (referenceWindow == null)
|
|
{
|
|
return;
|
|
}
|
|
|
|
Topmost = referenceWindow.Topmost;
|
|
}
|
|
|
|
public void SetMessage(string title, string subtitle)
|
|
{
|
|
if (!string.IsNullOrWhiteSpace(title))
|
|
{
|
|
TitleText.Text = title;
|
|
}
|
|
|
|
if (!string.IsNullOrWhiteSpace(subtitle))
|
|
{
|
|
SubtitleText.Text = subtitle;
|
|
}
|
|
}
|
|
|
|
public void CloseWhenReady()
|
|
{
|
|
if (_closeRequested)
|
|
{
|
|
return;
|
|
}
|
|
|
|
_closeRequested = true;
|
|
TimeSpan remaining = MinimumDisplayDuration - (DateTime.UtcNow - _shownAtUtc);
|
|
if (remaining <= TimeSpan.Zero)
|
|
{
|
|
CloseOverlay();
|
|
return;
|
|
}
|
|
|
|
DispatcherTimer timer = new DispatcherTimer(
|
|
remaining,
|
|
DispatcherPriority.Background,
|
|
OnCloseTimerTick,
|
|
Dispatcher);
|
|
timer.Start();
|
|
}
|
|
|
|
private void OnCloseTimerTick(object sender, EventArgs e)
|
|
{
|
|
DispatcherTimer timer = sender as DispatcherTimer;
|
|
if (timer != null)
|
|
{
|
|
timer.Stop();
|
|
timer.Tick -= OnCloseTimerTick;
|
|
}
|
|
|
|
CloseOverlay();
|
|
}
|
|
|
|
private void CloseOverlay()
|
|
{
|
|
if (Dispatcher.HasShutdownStarted || Dispatcher.HasShutdownFinished || !IsLoaded)
|
|
{
|
|
return;
|
|
}
|
|
|
|
DoubleAnimation fadeOutAnimation = new DoubleAnimation
|
|
{
|
|
From = Opacity,
|
|
To = 0,
|
|
Duration = new Duration(DismissAnimationDuration),
|
|
FillBehavior = FillBehavior.Stop
|
|
};
|
|
|
|
fadeOutAnimation.Completed += (sender, args) =>
|
|
{
|
|
if (Dispatcher.HasShutdownStarted || Dispatcher.HasShutdownFinished || !IsLoaded)
|
|
{
|
|
return;
|
|
}
|
|
|
|
Close();
|
|
};
|
|
|
|
BeginAnimation(OpacityProperty, fadeOutAnimation);
|
|
}
|
|
}
|
|
}
|