2025-08-20 12:10:13 +08:00
|
|
|
|
|
|
|
|
|
|
using System.ComponentModel;
|
|
|
|
|
|
using System.Runtime.CompilerServices;
|
|
|
|
|
|
using System.Windows.Media.Animation;
|
|
|
|
|
|
|
2026-01-02 17:30:30 +08:00
|
|
|
|
namespace VariaStudio.Controls;
|
2025-08-20 12:10:13 +08:00
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
|
/// SplashWindow 类表示一个启动窗口,用于在应用程序初始化时显示。它继承自 Window 并实现了 INotifyPropertyChanged 接口以支持属性更改通知。
|
|
|
|
|
|
/// 该类主要用于显示带有图片和提示信息的启动界面,并且可以设置自动结束或手动触发结束动画来关闭窗口。
|
|
|
|
|
|
/// </summary>
|
|
|
|
|
|
public sealed partial class SplashWindow : Window, INotifyPropertyChanged
|
|
|
|
|
|
{
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
|
/// 属性更改事件,当属性值发生变化时触发此事件。
|
|
|
|
|
|
/// 实现了INotifyPropertyChanged接口的类可以通过引发此事件来通知绑定客户端其属性值已经更改。
|
|
|
|
|
|
/// </summary>
|
|
|
|
|
|
public event PropertyChangedEventHandler? PropertyChanged;
|
|
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
|
/// 获取启动窗口显示的图像资源URI。此属性用于指定在SplashWindow中展示的图片的位置。
|
|
|
|
|
|
/// </summary>
|
|
|
|
|
|
public Uri ImageUri { get; }
|
|
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
|
/// 用于存储提示信息的字符串。此字段与Hint属性关联,当其值发生变化时会触发属性更改通知。
|
|
|
|
|
|
/// </summary>
|
|
|
|
|
|
private string hint = null!;
|
|
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
|
/// 获取或设置提示信息的字符串。此属性允许用户自定义显示在SplashWindow上的提示文本。当该属性值被修改时,会自动通知所有已注册的属性更改监听者。
|
|
|
|
|
|
/// </summary>
|
|
|
|
|
|
public string Hint
|
|
|
|
|
|
{
|
|
|
|
|
|
get => hint;
|
|
|
|
|
|
set => SetProperty(ref hint, value);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
|
///
|
|
|
|
|
|
/// </summary>
|
|
|
|
|
|
public bool AutoEnd { get; set; } = false;
|
|
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
|
///
|
|
|
|
|
|
/// </summary>
|
|
|
|
|
|
public DateTime TimeOfCtor = DateTime.Now;
|
|
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
|
///
|
|
|
|
|
|
/// </summary>
|
|
|
|
|
|
/// <param name="imageUri"></param>
|
|
|
|
|
|
public SplashWindow(Uri imageUri)
|
|
|
|
|
|
{
|
|
|
|
|
|
DataContext = this;
|
|
|
|
|
|
ImageUri = imageUri;
|
|
|
|
|
|
InitializeComponent();
|
|
|
|
|
|
|
|
|
|
|
|
MouseLeftButtonDown += (sender, _) =>
|
|
|
|
|
|
{
|
|
|
|
|
|
if (sender is DependencyObject depObject)
|
|
|
|
|
|
{
|
|
|
|
|
|
GetWindow(depObject)?.DragMove();
|
|
|
|
|
|
}
|
|
|
|
|
|
};
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
|
/// 触发属性更改事件,通知监听者指定属性的值已更改。
|
|
|
|
|
|
/// </summary>
|
|
|
|
|
|
/// <param name="e">包含属性更改信息的事件参数。</param>
|
|
|
|
|
|
private void OnPropertyChanged(PropertyChangedEventArgs e)
|
|
|
|
|
|
{
|
|
|
|
|
|
PropertyChanged?.Invoke(this, e);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
|
/// 触发属性更改事件,通知监听者指定属性的值已更改。
|
|
|
|
|
|
/// </summary>
|
|
|
|
|
|
/// <param name="propertyName">发生更改的属性名称,默认通过CallerMemberName特性自动获取。</param>
|
|
|
|
|
|
private void OnPropertyChanged([CallerMemberName] string? propertyName = null)
|
|
|
|
|
|
{
|
|
|
|
|
|
OnPropertyChanged(new PropertyChangedEventArgs(propertyName));
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
|
/// 设置属性值,并在属性值发生变化时触发属性更改通知。
|
|
|
|
|
|
/// </summary>
|
|
|
|
|
|
/// <typeparam name="T">属性的类型。</typeparam>
|
|
|
|
|
|
/// <param name="field">要设置的字段。</param>
|
|
|
|
|
|
/// <param name="newValue">新值。</param>
|
|
|
|
|
|
/// <param name="propertyName">属性名,默认通过CallerMemberName获取。</param>
|
|
|
|
|
|
/// <returns>如果属性值发生改变,则返回true;否则返回false。</returns>
|
|
|
|
|
|
private bool SetProperty<T>(ref T field, T newValue, [CallerMemberName] string? propertyName = null)
|
|
|
|
|
|
{
|
|
|
|
|
|
if (EqualityComparer<T>.Default.Equals(field, newValue))
|
|
|
|
|
|
{
|
|
|
|
|
|
return false;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
field = newValue;
|
|
|
|
|
|
OnPropertyChanged(propertyName);
|
|
|
|
|
|
return true;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
private void Start_Completed(object? sender, EventArgs e)
|
|
|
|
|
|
{
|
|
|
|
|
|
if (AutoEnd)
|
|
|
|
|
|
{
|
|
|
|
|
|
StartEnd();
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
|
/// 在Storyboard动画完成时调用此方法,用于执行窗口关闭操作。
|
|
|
|
|
|
/// </summary>
|
|
|
|
|
|
/// <param name="sender">触发事件的对象。</param>
|
|
|
|
|
|
/// <param name="e">事件参数。</param>
|
|
|
|
|
|
private void End_Completed(object? sender, EventArgs e)
|
|
|
|
|
|
{
|
|
|
|
|
|
Shutdown();
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
|
/// 开始执行结束动画。此方法通过调用Dispatcher来查找名为"End"的Storyboard资源并开始播放,从而实现窗口关闭或过渡效果。
|
|
|
|
|
|
/// </summary>
|
|
|
|
|
|
public void StartEnd()
|
|
|
|
|
|
{
|
|
|
|
|
|
Dispatcher.Invoke(() =>
|
|
|
|
|
|
{
|
|
|
|
|
|
var storyboard = (Storyboard)FindResource("End");
|
|
|
|
|
|
storyboard.Begin();
|
|
|
|
|
|
});
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
|
/// 关闭当前窗口,并停止与之关联的Dispatcher,以确保所有相关的UI线程活动被正确终止。
|
|
|
|
|
|
/// </summary>
|
|
|
|
|
|
public void Shutdown()
|
|
|
|
|
|
{
|
|
|
|
|
|
Dispatcher.Invoke(() =>
|
|
|
|
|
|
{
|
|
|
|
|
|
Close();
|
|
|
|
|
|
Dispatcher?.InvokeShutdown();
|
|
|
|
|
|
});
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|