using System; using System.Collections.ObjectModel; using System.IO; using System.Threading.Tasks; using System.Windows; using System.Windows.Controls; using System.Windows.Media; using System.Windows.Media.Animation; using Microsoft.Win32; namespace Better_Seewo.Manager.Pages { /// /// InkPage.xaml 的交互逻辑 /// 墨迹管理页面 - 导入和导出白板墨迹数据 /// public partial class InkPage : Page { // ===== 导出历史记录集合 ===== private ObservableCollection _exportHistory; // ===== 选中的导入文件路径 ===== private string _selectedImportFile = string.Empty; /// /// 导出记录数据模型 /// public class ExportRecord { public string FileName { get; set; } = string.Empty; public string FileSize { get; set; } = string.Empty; public string Time { get; set; } = string.Empty; } public InkPage() { InitializeComponent(); InitializeExportHistory(); Loaded += InkPage_Loaded; } /// /// 初始化导出历史列表 /// private void InitializeExportHistory() { _exportHistory = new ObservableCollection(); ExportHistoryList.ItemsSource = _exportHistory; } /// /// 页面加载时执行入场动画 /// private void InkPage_Loaded(object sender, RoutedEventArgs e) { PlayEntranceAnimation(); } /// /// 播放入场动画 /// private void PlayEntranceAnimation() { // 简单的淡入动画 var fadeAnimation = new DoubleAnimation { From = 0, To = 1, Duration = TimeSpan.FromMilliseconds(500), EasingFunction = new CubicEase { EasingMode = EasingMode.EaseOut } }; BeginAnimation(OpacityProperty, fadeAnimation); } /// /// 浏览导出保存路径 /// private void BtnBrowseExportPath_Click(object sender, RoutedEventArgs e) { var dialog = new SaveFileDialog { Filter = "墨迹文件 (*.ink.json)|*.ink.json", DefaultExt = ".ink.json", FileName = ExportFileName.Text }; if (dialog.ShowDialog() == true) { var directory = Path.GetDirectoryName(dialog.FileName); if (!string.IsNullOrEmpty(directory)) { ExportFolderPath.Text = directory; } } } /// /// 点击导入文件选择区域 /// private void ImportFileDropZone_Click(object sender, System.Windows.Input.MouseButtonEventArgs e) { var dialog = new OpenFileDialog { Filter = "墨迹文件 (*.ink.json)|*.ink.json", DefaultExt = ".ink.json", Title = "选择墨迹文件" }; if (dialog.ShowDialog() == true) { _selectedImportFile = dialog.FileName; ImportFileNameText.Text = Path.GetFileName(dialog.FileName); PreviewImportFile(dialog.FileName); BtnImport.IsEnabled = true; } } /// /// 预览选中的导入文件 /// private void PreviewImportFile(string filePath) { try { var fileInfo = new FileInfo(filePath); InkEmptyState.Visibility = Visibility.Collapsed; InkInfoPanel.Visibility = Visibility.Visible; // 显示文件基本信息 InkFileSizeText.Text = FormatFileSize(fileInfo.Length); InkFormatText.Text = Path.GetExtension(filePath); InkTimestampText.Text = fileInfo.LastWriteTime.ToString("yyyy-MM-dd HH:mm:ss"); // TODO: 解析ink.json获取实际笔画数 // 当前为模拟数据 StrokeCountText.Text = "128"; } catch (Exception) { InkEmptyState.Visibility = Visibility.Visible; InkInfoPanel.Visibility = Visibility.Collapsed; ImportFileNameText.Text = "文件读取失败"; BtnImport.IsEnabled = false; } } /// /// 格式化文件大小 /// private static string FormatFileSize(long bytes) { if (bytes < 1024) return $"{bytes} B"; if (bytes < 1024 * 1024) return $"{bytes / 1024.0:F1} KB"; return $"{bytes / (1024.0 * 1024.0):F1} MB"; } /// /// 执行导出操作(带进度动画) /// private async void BtnExport_Click(object sender, RoutedEventArgs e) { ExportProgressPanel.Visibility = Visibility.Visible; BtnExport.IsEnabled = false; try { await AnimateProgressAsync(ExportProgressBar, ExportProgressText, 0, 100, 2000); // TODO: 实际导出逻辑 - 序列化墨迹数据到ink.json文件 var fileName = $"{ExportFileName.Text}.ink.json"; var fullPath = Path.Combine(ExportFolderPath.Text, fileName); // 添加到导出历史 _exportHistory.Insert(0, new ExportRecord { FileName = fileName, FileSize = "模拟数据", Time = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss") }); // 最多保留10条记录 while (_exportHistory.Count > 10) _exportHistory.RemoveAt(_exportHistory.Count - 1); } finally { ExportProgressPanel.Visibility = Visibility.Collapsed; BtnExport.IsEnabled = true; } } /// /// 执行导入操作(带进度动画) /// private async void BtnImport_Click(object sender, RoutedEventArgs e) { if (string.IsNullOrEmpty(_selectedImportFile)) return; ImportProgressPanel.Visibility = Visibility.Visible; BtnImport.IsEnabled = false; try { await AnimateProgressAsync(ImportProgressBar, ImportProgressText, 0, 100, 1500); // TODO: 实际导入逻辑 - 读取ink.json并应用到白板 } finally { ImportProgressPanel.Visibility = Visibility.Collapsed; BtnImport.IsEnabled = true; } } /// /// 播放进度条动画 /// private async Task AnimateProgressAsync(FrameworkElement progressBar, TextBlock progressText, double from, double to, int durationMs) { var steps = 20; var stepMs = durationMs / steps; var increment = (to - from) / steps; for (int i = 0; i <= steps; i++) { var value = from + increment * i; var percent = (int)Math.Round(value); // 通过Dispatcher更新UI Dispatcher.Invoke(() => { progressText.Text = $"{percent}%"; var scaleX = value / 100.0; var animation = new DoubleAnimation { From = progressBar.RenderTransform is ScaleTransform st ? st.ScaleX : scaleX, To = scaleX, Duration = TimeSpan.FromMilliseconds(stepMs), EasingFunction = new QuadraticEase { EasingMode = EasingMode.EaseInOut } }; progressBar.RenderTransform = new ScaleTransform(scaleX, 1); }); await Task.Delay(stepMs); } } } }