feat(01-06): build WPF shell — MainWindow XAML, ViewModels, LogPanelSink wiring

- Add FeatureTabBase UserControl with ProgressBar/TextBlock/CancelButton strip
  (Visibility bound to IsRunning, shown only during operations)
- Add MainWindowViewModel with TenantProfiles ObservableCollection, ConnectCommand,
  ClearSessionCommand, ManageProfilesCommand, ProgressUpdatedMessage subscription
- Add ProfileManagementViewModel wrapping ProfileService CRUD with input validation
- Add SettingsViewModel (extends FeatureViewModelBase) with language/folder settings
- Update MainWindow.xaml: DockPanel shell with Toolbar, TabControl (8 tabs), 150px
  RichTextBox LogPanel, StatusBar (tenant name | ProgressStatus | ProgressPercentage)
- MainWindow.xaml.cs: DI constructor, DataContext=viewModel, LoadProfilesAsync on Loaded
- App.xaml.cs: register all services, wire LogPanelSink after MainWindow resolved,
  register DispatcherUnhandledException and UnobservedTaskException global handlers
- App.xaml: add BoolToVisibilityConverter resource
This commit is contained in:
Dev
2026-04-02 12:32:41 +02:00
parent 3c09155648
commit 5920d42614
9 changed files with 516 additions and 27 deletions

View File

@@ -1,23 +1,26 @@
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
using SharepointToolbox.ViewModels;
namespace SharepointToolbox;
/// <summary>
/// Interaction logic for MainWindow.xaml
/// </summary>
public partial class MainWindow : Window
{
public MainWindow()
private readonly MainWindowViewModel _viewModel;
public MainWindow(MainWindowViewModel viewModel)
{
InitializeComponent();
_viewModel = viewModel;
DataContext = viewModel;
Loaded += OnLoaded;
}
}
private async void OnLoaded(object sender, RoutedEventArgs e)
{
await _viewModel.LoadProfilesAsync();
}
// Expose the LogPanel RichTextBox (generated by x:Name="LogPanel") for LogPanelSink wiring
public RichTextBox GetLogPanel() => LogPanel;
}