2.7 KiB
TeamsISO Phase C — WPF MVVM UI Plan
Goal: Operator-facing WPF UI bound to IIsoController. Displays the live participant list, lets operators enable/disable per-participant ISO outputs, set the global framerate / resolution / aspect / audio mode, view engine alerts, and see basic system health. Plus a WiX MSI installer and a release CI pipeline.
Architecture: MVVM with no third-party MVVM framework — small managed ObservableObject and RelayCommand helpers. The view models bind directly to IIsoController's observables. UI runs on the WPF dispatcher; observable subscriptions marshal back via a captured SynchronizationContext. App.xaml.cs constructs the engine on startup and disposes on exit.
Tech stack: WPF on .NET 8, MVVM hand-rolled, no external UI library yet (MaterialDesignThemes can be added in a polish pass).
File structure additions
src/TeamsISO.App/
├── App.xaml / App.xaml.cs (DI bootstrap)
├── MainWindow.xaml / MainWindow.xaml.cs
├── ViewModels/
│ ├── ObservableObject.cs
│ ├── RelayCommand.cs
│ ├── MainViewModel.cs
│ ├── ParticipantViewModel.cs
│ ├── GlobalSettingsViewModel.cs
│ └── AlertBannerViewModel.cs
├── Converters/
│ ├── BoolToVisibilityConverter.cs
│ └── EnumDescriptionConverter.cs
└── TeamsISO.App.csproj
src/TeamsISO.Installer/
└── TeamsISO.Installer.wixproj (MSI installer; v5)
Tasks
- MVVM helpers —
ObservableObjectbase implementingINotifyPropertyChanged;RelayCommandandAsyncRelayCommand. - GlobalSettingsViewModel — exposes Framerate, Resolution, Aspect, Audio as bindable selected values;
Applycommand callscontroller.SetGlobalSettingsAsync. - ParticipantViewModel — wraps a
Participant, exposes IsEnabled, CustomOutputName, and current status;EnableCommandandDisableCommandcall the controller. - AlertBannerViewModel — collects
EngineAlerts and exposes the most recent one with a "dismiss" command. - MainViewModel — top-level. Owns the controller. Exposes
ObservableCollection<ParticipantViewModel>, the settings VM, and the banner VM. - MainWindow.xaml — DataGrid for participants with toggle column, settings panel docked to the right, alert banner docked top.
- Converters — bool→visibility, enum→display string.
- App.xaml.cs — wires DI: build engine + controller + main view model, set MainWindow's DataContext, dispose on exit.
- WiX installer (Phase C-2) — separate task; can ship after the UI is alive.
Each step ships as its own commit. Tag phase-c-complete after MainWindow renders and the controller is bound.