355 lines
12 KiB
C#
355 lines
12 KiB
C#
|
|
/*
|
|||
|
|
* MainWindow.xaml.cs - Better-Seewo 安装向导主窗口逻辑
|
|||
|
|
* 负责安装步骤管理(Welcome -> Install -> Complete)、页面导航动画、按钮逻辑和关闭确认
|
|||
|
|
* 作者:雾启工作室
|
|||
|
|
*/
|
|||
|
|
|
|||
|
|
using System;
|
|||
|
|
using System.Windows;
|
|||
|
|
using System.Windows.Controls;
|
|||
|
|
using System.Windows.Input;
|
|||
|
|
using System.Windows.Media;
|
|||
|
|
using System.Windows.Media.Animation;
|
|||
|
|
|
|||
|
|
namespace Better_Seewo.Installer
|
|||
|
|
{
|
|||
|
|
/// <summary>
|
|||
|
|
/// MainWindow 的交互逻辑 - Fluent Design 风格安装向导主窗口
|
|||
|
|
/// </summary>
|
|||
|
|
public partial class MainWindow : Window
|
|||
|
|
{
|
|||
|
|
/// <summary>
|
|||
|
|
/// 页面切换动画时长(毫秒)
|
|||
|
|
/// </summary>
|
|||
|
|
private const int PageTransitionDuration = 300;
|
|||
|
|
|
|||
|
|
/// <summary>
|
|||
|
|
/// 进度指示器动画时长(毫秒)
|
|||
|
|
/// </summary>
|
|||
|
|
private const int DotAnimationDuration = 300;
|
|||
|
|
|
|||
|
|
/// <summary>
|
|||
|
|
/// 当前安装步骤索引(0=欢迎页, 1=安装页, 2=完成页)
|
|||
|
|
/// </summary>
|
|||
|
|
private int _currentStep = 0;
|
|||
|
|
|
|||
|
|
/// <summary>
|
|||
|
|
/// 构造函数,初始化窗口组件
|
|||
|
|
/// </summary>
|
|||
|
|
public MainWindow()
|
|||
|
|
{
|
|||
|
|
InitializeComponent();
|
|||
|
|
|
|||
|
|
// 为所有按钮初始化 RenderTransform(用于悬停缩放动画)
|
|||
|
|
BtnNext.RenderTransform = new ScaleTransform(1.0, 1.0);
|
|||
|
|
BtnInstall.RenderTransform = new ScaleTransform(1.0, 1.0);
|
|||
|
|
BtnFinish.RenderTransform = new ScaleTransform(1.0, 1.0);
|
|||
|
|
BtnBack.RenderTransform = new ScaleTransform(1.0, 1.0);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/// <summary>
|
|||
|
|
/// 窗口加载完成事件处理 - 导航到默认欢迎页
|
|||
|
|
/// </summary>
|
|||
|
|
private void Window_Loaded(object sender, RoutedEventArgs e)
|
|||
|
|
{
|
|||
|
|
// 导航到欢迎页
|
|||
|
|
NavigateToPage(new Pages.WelcomePage());
|
|||
|
|
// 设置按钮状态
|
|||
|
|
UpdateButtonStates();
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
#region ===== 自定义标题栏拖动 =====
|
|||
|
|
|
|||
|
|
/// <summary>
|
|||
|
|
/// 标题栏鼠标左键按下 - 实现窗口拖动
|
|||
|
|
/// </summary>
|
|||
|
|
private void TitleBar_MouseLeftButtonDown(object sender, MouseButtonEventArgs e)
|
|||
|
|
{
|
|||
|
|
// 如果点击的是按钮区域则不触发拖动
|
|||
|
|
if (e.Source is Button) return;
|
|||
|
|
|
|||
|
|
// 调用 DragMove 实现窗口拖动
|
|||
|
|
if (e.LeftButton == MouseButtonState.Pressed)
|
|||
|
|
{
|
|||
|
|
DragMove();
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
#endregion
|
|||
|
|
|
|||
|
|
#region ===== 窗口关闭 =====
|
|||
|
|
|
|||
|
|
/// <summary>
|
|||
|
|
/// 关闭按钮点击 - 安装进行中不允许关闭
|
|||
|
|
/// </summary>
|
|||
|
|
private void BtnClose_Click(object sender, RoutedEventArgs e)
|
|||
|
|
{
|
|||
|
|
// 安装进行中时禁止关闭
|
|||
|
|
if (App.IsInstalling)
|
|||
|
|
{
|
|||
|
|
MessageBox.Show(
|
|||
|
|
"安装正在进行中,请等待安装完成后再关闭。",
|
|||
|
|
"Better-Seewo 安装程序",
|
|||
|
|
MessageBoxButton.OK,
|
|||
|
|
MessageBoxImage.Information
|
|||
|
|
);
|
|||
|
|
return;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
// 安装已完成或未开始时,确认关闭
|
|||
|
|
if (App.IsInstallCompleted)
|
|||
|
|
{
|
|||
|
|
Application.Current.Shutdown();
|
|||
|
|
return;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
// 未完成安装时二次确认
|
|||
|
|
var result = MessageBox.Show(
|
|||
|
|
"安装尚未完成,确定要退出安装程序吗?",
|
|||
|
|
"Better-Seewo 安装程序",
|
|||
|
|
MessageBoxButton.YesNo,
|
|||
|
|
MessageBoxImage.Question
|
|||
|
|
);
|
|||
|
|
|
|||
|
|
if (result == MessageBoxResult.Yes)
|
|||
|
|
{
|
|||
|
|
Application.Current.Shutdown();
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
#endregion
|
|||
|
|
|
|||
|
|
#region ===== 按钮事件处理 =====
|
|||
|
|
|
|||
|
|
/// <summary>
|
|||
|
|
/// 下一步按钮点击 - 从欢迎页跳转到安装页
|
|||
|
|
/// </summary>
|
|||
|
|
private void BtnNext_Click(object sender, RoutedEventArgs e)
|
|||
|
|
{
|
|||
|
|
if (_currentStep == 0)
|
|||
|
|
{
|
|||
|
|
// 从欢迎页进入安装页
|
|||
|
|
_currentStep = 1;
|
|||
|
|
NavigateToPage(new Pages.InstallPage());
|
|||
|
|
UpdateButtonStates();
|
|||
|
|
UpdateProgressDots();
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/// <summary>
|
|||
|
|
/// 安装按钮点击 - 开始执行安装
|
|||
|
|
/// </summary>
|
|||
|
|
private void BtnInstall_Click(object sender, RoutedEventArgs e)
|
|||
|
|
{
|
|||
|
|
if (ContentFrame.Content is Pages.InstallPage installPage)
|
|||
|
|
{
|
|||
|
|
// 标记安装开始
|
|||
|
|
App.IsInstalling = true;
|
|||
|
|
App.InstallStartTime = DateTime.Now;
|
|||
|
|
|
|||
|
|
// 禁用安装按钮,显示返回按钮不可用
|
|||
|
|
BtnInstall.IsEnabled = false;
|
|||
|
|
BtnInstall.Content = "正在安装...";
|
|||
|
|
BtnBack.IsEnabled = false;
|
|||
|
|
|
|||
|
|
// 启动安装过程
|
|||
|
|
installPage.StartInstallation();
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/// <summary>
|
|||
|
|
/// 返回按钮点击 - 返回上一步
|
|||
|
|
/// </summary>
|
|||
|
|
private void BtnBack_Click(object sender, RoutedEventArgs e)
|
|||
|
|
{
|
|||
|
|
if (_currentStep == 1)
|
|||
|
|
{
|
|||
|
|
// 从安装页返回欢迎页
|
|||
|
|
_currentStep = 0;
|
|||
|
|
NavigateToPage(new Pages.WelcomePage());
|
|||
|
|
UpdateButtonStates();
|
|||
|
|
UpdateProgressDots();
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/// <summary>
|
|||
|
|
/// 完成按钮点击 - 关闭安装程序
|
|||
|
|
/// </summary>
|
|||
|
|
private void BtnFinish_Click(object sender, RoutedEventArgs e)
|
|||
|
|
{
|
|||
|
|
Application.Current.Shutdown();
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
#endregion
|
|||
|
|
|
|||
|
|
#region ===== 页面导航 =====
|
|||
|
|
|
|||
|
|
/// <summary>
|
|||
|
|
/// 导航到指定页面,带淡出旧页面 -> 新页面从右侧滑入的动画效果
|
|||
|
|
/// </summary>
|
|||
|
|
/// <param name="page">要导航到的 Page 实例</param>
|
|||
|
|
private void NavigateToPage(Page page)
|
|||
|
|
{
|
|||
|
|
// 步骤1:淡出当前页面
|
|||
|
|
var fadeOutAnimation = new DoubleAnimation
|
|||
|
|
{
|
|||
|
|
From = 1.0,
|
|||
|
|
To = 0.0,
|
|||
|
|
Duration = TimeSpan.FromMilliseconds(PageTransitionDuration / 2),
|
|||
|
|
EasingFunction = new CubicEase { EasingMode = EasingMode.EaseIn }
|
|||
|
|
};
|
|||
|
|
|
|||
|
|
fadeOutAnimation.Completed += (s, e) =>
|
|||
|
|
{
|
|||
|
|
// 步骤2:切换到新页面
|
|||
|
|
ContentFrame.Navigate(page);
|
|||
|
|
|
|||
|
|
// 步骤3:新页面从右侧滑入 + 淡入
|
|||
|
|
var translateAnimation = new DoubleAnimation
|
|||
|
|
{
|
|||
|
|
From = 30.0,
|
|||
|
|
To = 0.0,
|
|||
|
|
Duration = TimeSpan.FromMilliseconds(PageTransitionDuration / 2),
|
|||
|
|
EasingFunction = new CubicEase { EasingMode = EasingMode.EaseOut }
|
|||
|
|
};
|
|||
|
|
|
|||
|
|
var fadeInAnimation = new DoubleAnimation
|
|||
|
|
{
|
|||
|
|
From = 0.0,
|
|||
|
|
To = 1.0,
|
|||
|
|
Duration = TimeSpan.FromMilliseconds(PageTransitionDuration / 2),
|
|||
|
|
EasingFunction = new CubicEase { EasingMode = EasingMode.EaseOut }
|
|||
|
|
};
|
|||
|
|
|
|||
|
|
// 应用水平偏移动画
|
|||
|
|
ContentFrame.BeginAnimation(
|
|||
|
|
FrameworkElement.RenderTransformOriginProperty, null);
|
|||
|
|
var translateTransform = new TranslateTransform(30, 0);
|
|||
|
|
ContentFrame.RenderTransform = translateTransform;
|
|||
|
|
translateTransform.BeginAnimation(TranslateTransform.XProperty, translateAnimation);
|
|||
|
|
|
|||
|
|
// 应用淡入动画
|
|||
|
|
ContentFrame.BeginAnimation(OpacityProperty, fadeInAnimation);
|
|||
|
|
};
|
|||
|
|
|
|||
|
|
// 应用淡出动画到 Frame
|
|||
|
|
ContentFrame.BeginAnimation(OpacityProperty, fadeOutAnimation);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/// <summary>
|
|||
|
|
/// 根据当前步骤更新按钮的可见性和状态
|
|||
|
|
/// </summary>
|
|||
|
|
private void UpdateButtonStates()
|
|||
|
|
{
|
|||
|
|
switch (_currentStep)
|
|||
|
|
{
|
|||
|
|
case 0: // 欢迎页
|
|||
|
|
BtnBack.Visibility = Visibility.Collapsed;
|
|||
|
|
BtnNext.Visibility = Visibility.Visible;
|
|||
|
|
BtnInstall.Visibility = Visibility.Collapsed;
|
|||
|
|
BtnFinish.Visibility = Visibility.Collapsed;
|
|||
|
|
BtnNext.IsEnabled = true;
|
|||
|
|
BtnNext.Content = "下一步 \uE74E;";
|
|||
|
|
break;
|
|||
|
|
|
|||
|
|
case 1: // 安装页
|
|||
|
|
BtnBack.Visibility = Visibility.Visible;
|
|||
|
|
BtnBack.IsEnabled = true;
|
|||
|
|
BtnNext.Visibility = Visibility.Collapsed;
|
|||
|
|
BtnInstall.Visibility = Visibility.Visible;
|
|||
|
|
BtnInstall.IsEnabled = true;
|
|||
|
|
BtnInstall.Content = "开始安装 \uE74E;";
|
|||
|
|
BtnFinish.Visibility = Visibility.Collapsed;
|
|||
|
|
break;
|
|||
|
|
|
|||
|
|
case 2: // 完成页
|
|||
|
|
BtnBack.Visibility = Visibility.Collapsed;
|
|||
|
|
BtnNext.Visibility = Visibility.Collapsed;
|
|||
|
|
BtnInstall.Visibility = Visibility.Collapsed;
|
|||
|
|
BtnFinish.Visibility = Visibility.Visible;
|
|||
|
|
break;
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/// <summary>
|
|||
|
|
/// 更新底部进度指示器圆点的颜色,高亮当前步骤
|
|||
|
|
/// </summary>
|
|||
|
|
private void UpdateProgressDots()
|
|||
|
|
{
|
|||
|
|
// 获取主题中的画刷资源
|
|||
|
|
var accentBrush = (Brush)FindResource("AccentBrush");
|
|||
|
|
var borderBrush = (Brush)FindResource("BorderBrush");
|
|||
|
|
|
|||
|
|
// 更新三个圆点的颜色
|
|||
|
|
Dot1.Fill = _currentStep >= 0 ? accentBrush : borderBrush;
|
|||
|
|
Dot2.Fill = _currentStep >= 1 ? accentBrush : borderBrush;
|
|||
|
|
Dot3.Fill = _currentStep >= 2 ? accentBrush : borderBrush;
|
|||
|
|
|
|||
|
|
// 为当前圆点播放缩放动画(突出当前步骤)
|
|||
|
|
var currentDot = _currentStep switch
|
|||
|
|
{
|
|||
|
|
0 => Dot1,
|
|||
|
|
1 => Dot2,
|
|||
|
|
2 => Dot3,
|
|||
|
|
_ => Dot1
|
|||
|
|
};
|
|||
|
|
|
|||
|
|
AnimateDotScale(currentDot);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/// <summary>
|
|||
|
|
/// 为进度指示器圆点播放缩放脉冲动画
|
|||
|
|
/// </summary>
|
|||
|
|
private void AnimateDotScale(FrameworkElement dot)
|
|||
|
|
{
|
|||
|
|
// 放大到 1.5 倍再缩回 1.0 倍
|
|||
|
|
var scaleUpAnimation = new DoubleAnimation
|
|||
|
|
{
|
|||
|
|
From = 1.0,
|
|||
|
|
To = 1.5,
|
|||
|
|
Duration = TimeSpan.FromMilliseconds(DotAnimationDuration),
|
|||
|
|
EasingFunction = new CubicEase { EasingMode = EasingMode.EaseOut }
|
|||
|
|
};
|
|||
|
|
|
|||
|
|
var scaleDownAnimation = new DoubleAnimation
|
|||
|
|
{
|
|||
|
|
From = 1.5,
|
|||
|
|
To = 1.0,
|
|||
|
|
Duration = TimeSpan.FromMilliseconds(DotAnimationDuration),
|
|||
|
|
EasingFunction = new CubicEase { EasingMode = EasingMode.EaseIn },
|
|||
|
|
BeginTime = TimeSpan.FromMilliseconds(DotAnimationDuration)
|
|||
|
|
};
|
|||
|
|
|
|||
|
|
// 设置缩放变换中心点
|
|||
|
|
dot.RenderTransform = new ScaleTransform(1.0, 1.0, 4, 4);
|
|||
|
|
|
|||
|
|
// 应用缩放动画
|
|||
|
|
dot.RenderTransform.BeginAnimation(ScaleTransform.ScaleXProperty, scaleUpAnimation);
|
|||
|
|
dot.RenderTransform.BeginAnimation(ScaleTransform.ScaleXProperty, scaleDownAnimation);
|
|||
|
|
dot.RenderTransform.BeginAnimation(ScaleTransform.ScaleYProperty, scaleUpAnimation);
|
|||
|
|
dot.RenderTransform.BeginAnimation(ScaleTransform.ScaleYProperty, scaleDownAnimation);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/// <summary>
|
|||
|
|
/// 安装完成后由 InstallPage 调用,切换到完成页
|
|||
|
|
/// </summary>
|
|||
|
|
public void OnInstallCompleted()
|
|||
|
|
{
|
|||
|
|
// 标记安装完成
|
|||
|
|
App.IsInstalling = false;
|
|||
|
|
App.IsInstallCompleted = true;
|
|||
|
|
|
|||
|
|
// 切换到完成页
|
|||
|
|
Dispatcher.Invoke(() =>
|
|||
|
|
{
|
|||
|
|
_currentStep = 2;
|
|||
|
|
NavigateToPage(new Pages.CompletePage());
|
|||
|
|
UpdateButtonStates();
|
|||
|
|
UpdateProgressDots();
|
|||
|
|
});
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
#endregion
|
|||
|
|
}
|
|||
|
|
}
|