From e08452d1bfa329a0c0b280d0e79d47083f8b62ae Mon Sep 17 00:00:00 2001 From: Dev Date: Thu, 2 Apr 2026 15:38:20 +0200 Subject: [PATCH] feat(03-07): create StorageView XAML, DI registration, and MainWindow wiring - StorageView.xaml: DataGrid with IndentLevel-based name indentation - StorageView.xaml.cs: code-behind wiring DataContext to StorageViewModel - IndentConverter.cs: IndentConverter, BytesConverter, InverseBoolConverter - App.xaml: register converters and RightAlignStyle as Application.Resources - App.xaml.cs: register IStorageService, StorageCsvExportService, StorageHtmlExportService, StorageViewModel, StorageView - MainWindow.xaml: add x:Name=StorageTabItem to Storage TabItem - MainWindow.xaml.cs: wire StorageTabItem.Content from DI --- SharepointToolbox/App.xaml | 9 +- SharepointToolbox/App.xaml.cs | 7 ++ SharepointToolbox/MainWindow.xaml | 4 +- SharepointToolbox/MainWindow.xaml.cs | 3 + .../Views/Converters/IndentConverter.cs | 47 ++++++++ SharepointToolbox/Views/Tabs/StorageView.xaml | 104 ++++++++++++++++++ .../Views/Tabs/StorageView.xaml.cs | 12 ++ 7 files changed, 183 insertions(+), 3 deletions(-) create mode 100644 SharepointToolbox/Views/Converters/IndentConverter.cs create mode 100644 SharepointToolbox/Views/Tabs/StorageView.xaml create mode 100644 SharepointToolbox/Views/Tabs/StorageView.xaml.cs diff --git a/SharepointToolbox/App.xaml b/SharepointToolbox/App.xaml index b937526..a78f1da 100644 --- a/SharepointToolbox/App.xaml +++ b/SharepointToolbox/App.xaml @@ -1,8 +1,15 @@ + xmlns:local="clr-namespace:SharepointToolbox" + xmlns:conv="clr-namespace:SharepointToolbox.Views.Converters"> + + + + diff --git a/SharepointToolbox/App.xaml.cs b/SharepointToolbox/App.xaml.cs index 692bbb8..28a16c3 100644 --- a/SharepointToolbox/App.xaml.cs +++ b/SharepointToolbox/App.xaml.cs @@ -88,6 +88,13 @@ public partial class App : Application services.AddTransient(); services.AddTransient(); + // Phase 3: Storage + services.AddTransient(); + services.AddTransient(); + services.AddTransient(); + services.AddTransient(); + services.AddTransient(); + // Phase 2: Permissions services.AddTransient(); services.AddTransient(); diff --git a/SharepointToolbox/MainWindow.xaml b/SharepointToolbox/MainWindow.xaml index 7f01def..f9546a1 100644 --- a/SharepointToolbox/MainWindow.xaml +++ b/SharepointToolbox/MainWindow.xaml @@ -44,8 +44,8 @@ - - + diff --git a/SharepointToolbox/MainWindow.xaml.cs b/SharepointToolbox/MainWindow.xaml.cs index 6e7cc9b..092e2d9 100644 --- a/SharepointToolbox/MainWindow.xaml.cs +++ b/SharepointToolbox/MainWindow.xaml.cs @@ -23,6 +23,9 @@ public partial class MainWindow : Window // Replace Permissions tab placeholder with the DI-resolved PermissionsView PermissionsTabItem.Content = serviceProvider.GetRequiredService(); + // Replace Storage tab placeholder with the DI-resolved StorageView + StorageTabItem.Content = serviceProvider.GetRequiredService(); + // Replace Settings tab placeholder with the DI-resolved SettingsView SettingsTabItem.Content = serviceProvider.GetRequiredService(); diff --git a/SharepointToolbox/Views/Converters/IndentConverter.cs b/SharepointToolbox/Views/Converters/IndentConverter.cs new file mode 100644 index 0000000..ee89a72 --- /dev/null +++ b/SharepointToolbox/Views/Converters/IndentConverter.cs @@ -0,0 +1,47 @@ +using System.Globalization; +using System.Windows; +using System.Windows.Data; + +namespace SharepointToolbox.Views.Converters; + +/// Converts IndentLevel (int) to WPF Thickness for DataGrid indent. +[ValueConversion(typeof(int), typeof(Thickness))] +public class IndentConverter : IValueConverter +{ + public object Convert(object value, Type targetType, object parameter, CultureInfo culture) + { + int level = value is int i ? i : 0; + return new Thickness(level * 16, 0, 0, 0); + } + + public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture) + => throw new NotImplementedException(); +} + +/// Converts byte count (long) to human-readable size string. +[ValueConversion(typeof(long), typeof(string))] +public class BytesConverter : IValueConverter +{ + public object Convert(object value, Type targetType, object parameter, CultureInfo culture) + { + long bytes = value is long l ? l : 0L; + if (bytes >= 1_073_741_824L) return $"{bytes / 1_073_741_824.0:F2} GB"; + if (bytes >= 1_048_576L) return $"{bytes / 1_048_576.0:F2} MB"; + if (bytes >= 1024L) return $"{bytes / 1024.0:F2} KB"; + return $"{bytes} B"; + } + + public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture) + => throw new NotImplementedException(); +} + +/// Inverts a bool binding — used to disable controls while an operation is running. +[ValueConversion(typeof(bool), typeof(bool))] +public class InverseBoolConverter : IValueConverter +{ + public object Convert(object value, Type targetType, object parameter, CultureInfo culture) + => value is bool b && !b; + + public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture) + => value is bool b && !b; +} diff --git a/SharepointToolbox/Views/Tabs/StorageView.xaml b/SharepointToolbox/Views/Tabs/StorageView.xaml new file mode 100644 index 0000000..16b5788 --- /dev/null +++ b/SharepointToolbox/Views/Tabs/StorageView.xaml @@ -0,0 +1,104 @@ + + + + + + +