Files
OwnCord/Client/OwnCord.Client/ViewModels/RelayCommand.cs
T
jevb 9707c4d4af feat: scaffold Phase 3 WPF client shell with MVVM and TDD structure
- WPF (.NET 8) project targeting net8.0-windows
- Models: ServerProfile (record), Channel, Message, User, Role
- ViewModels: ViewModelBase (INotifyPropertyChanged), RelayCommand<T>,
  ConnectViewModel (profiles, login/register toggle, connect command),
  MainViewModel (channels, messages, typing indicator, send command),
  SettingsViewModel (dark theme, notifications, PTT key)
- Services: IProfileService + ProfileService (AppData JSON, immutable ops),
  ICredentialService + CredentialService (DPAPI via ProtectedData),
  IWebSocketService + WebSocketService (ClientWebSocket stub)
- Views: ConnectPage (server address, login/register, profile selector),
  MainPage (3-column: channel list, message area, member list),
  App.xaml wires converters and startup
- Converters: BoolToVisibilityConverter, IntToVisibilityConverter
- Tests: ConnectViewModelTests (11 cases), MainViewModelTests (11 cases),
  ProfileServiceTests (6 cases) — ready to run once NuGet accessible
  (run: dotnet restore && dotnet test OwnCord.Client.Tests/)

Build: dotnet build OwnCord.Client/ succeeds with 0 warnings
2026-03-14 21:07:07 +01:00

28 lines
877 B
C#

using System.Windows.Input;
namespace OwnCord.Client.ViewModels;
public sealed class RelayCommand(Action execute, Func<bool>? canExecute = null) : ICommand
{
public event EventHandler? CanExecuteChanged;
public bool CanExecute(object? parameter) => canExecute?.Invoke() ?? true;
public void Execute(object? parameter) => execute();
public void RaiseCanExecuteChanged() =>
CanExecuteChanged?.Invoke(this, EventArgs.Empty);
}
public sealed class RelayCommand<T>(Action<T?> execute, Func<T?, bool>? canExecute = null) : ICommand
{
public event EventHandler? CanExecuteChanged;
public bool CanExecute(object? parameter) => canExecute?.Invoke((T?)parameter) ?? true;
public void Execute(object? parameter) => execute((T?)parameter);
public void RaiseCanExecuteChanged() =>
CanExecuteChanged?.Invoke(this, EventArgs.Empty);
}