using Microsoft.UI.Xaml; using Microsoft.UI.Xaml.Data; namespace FluidExplorer.Helpers; /// bool → Visibility(ConverterParameter="invert" 可反转)。 public sealed class BoolToVisibilityConverter : IValueConverter { public object Convert(object value, Type targetType, object parameter, string language) { var flag = value is bool b && b; if (parameter is string s && s.Equals("invert", StringComparison.OrdinalIgnoreCase)) flag = !flag; return flag ? Visibility.Visible : Visibility.Collapsed; } public object ConvertBack(object value, Type targetType, object parameter, string language) => value is Visibility v && v == Visibility.Visible; } /// 字符串非空 → Visible。 public sealed class StringToVisibilityConverter : IValueConverter { public object Convert(object value, Type targetType, object parameter, string language) => string.IsNullOrWhiteSpace(value as string) ? Visibility.Collapsed : Visibility.Visible; public object ConvertBack(object value, Type targetType, object parameter, string language) => throw new NotSupportedException(); } /// 数量 > 0 → Visible。 public sealed class CountToVisibilityConverter : IValueConverter { public object Convert(object value, Type targetType, object parameter, string language) => value is int count && count > 0 ? Visibility.Visible : Visibility.Collapsed; public object ConvertBack(object value, Type targetType, object parameter, string language) => throw new NotSupportedException(); } /// bool 取反。 public sealed class InverseBoolConverter : IValueConverter { public object Convert(object value, Type targetType, object parameter, string language) => value is bool b && !b; public object ConvertBack(object value, Type targetType, object parameter, string language) => value is bool b && !b; } /// 回收站/图库等视图才显示的操作按钮。 public sealed class KindToVisibilityConverter : IValueConverter { public object Convert(object value, Type targetType, object parameter, string language) { var current = value?.ToString(); var expected = parameter as string; return string.Equals(current, expected, StringComparison.OrdinalIgnoreCase) ? Visibility.Visible : Visibility.Collapsed; } public object ConvertBack(object value, Type targetType, object parameter, string language) => throw new NotSupportedException(); } /// 作业状态 → 中文文案(状态栏/队列面板用)。 public sealed class JobStateTextConverter : IValueConverter { public object Convert(object value, Type targetType, object parameter, string language) => value is Services.Operations.JobState state ? state switch { Services.Operations.JobState.Queued => "排队中", Services.Operations.JobState.Running => "进行中", Services.Operations.JobState.Paused => "已暂停", Services.Operations.JobState.Completed => "已完成", Services.Operations.JobState.CompletedWithErrors => "已完成(部分出错)", Services.Operations.JobState.Cancelled => "已取消", Services.Operations.JobState.Failed => "失败", _ => state.ToString() } : string.Empty; public object ConvertBack(object value, Type targetType, object parameter, string language) => throw new NotSupportedException(); } /// 作业 → 进度明细文案:条目数 / 体积 / 速度 / 剩余时间。 public sealed class JobProgressTextConverter : IValueConverter { public object Convert(object value, Type targetType, object parameter, string language) { if (value is not Services.Operations.FileOperationJob job) return string.Empty; var parts = new List { $"{job.CompletedItems:N0} / {job.TotalItems:N0} 个项目" }; if (job.TotalBytes > 0) parts.Add($"{Models.FileEntry.FormatSize(job.CompletedBytes)} / {Models.FileEntry.FormatSize(job.TotalBytes)}"); if (job.BytesPerSecond > 1) parts.Add($"{Models.FileEntry.FormatSize((long)job.BytesPerSecond)}/s"); if (job.Eta is { } eta && eta.TotalSeconds > 1 && eta.TotalHours < 24) parts.Add($"剩余 {eta:mm\\:ss}"); if (!string.IsNullOrEmpty(job.Error)) parts.Add(job.Error!); return string.Join(" · ", parts); } public object ConvertBack(object value, Type targetType, object parameter, string language) => throw new NotSupportedException(); } /// 作业 → 暂停/继续按钮图标。 public sealed class JobPauseGlyphConverter : IValueConverter { public object Convert(object value, Type targetType, object parameter, string language) => value is Services.Operations.JobState.Paused ? "\uE768" : "\uE769"; public object ConvertBack(object value, Type targetType, object parameter, string language) => throw new NotSupportedException(); }