using CommunityToolkit.Mvvm.ComponentModel; using CommunityToolkit.Mvvm.Input; using CommunityToolkit.Mvvm.Messaging; using MultiTerm.Protocols.Types; namespace MultiTerm.Protocols; /// /// Class that represents all connection and usage settings for a specific . /// Can be bound to UI using MVVM pattern. /// Implementing class must also implement ! Otherwise does not work. /// public abstract partial class ProtocolSettingsViewModel : ObservableObject, IProtocolSettingsViewModel { private const string connectedStateButtonText = "Disconnect"; private const string disconnectedStateButtonText = "Connect"; protected readonly IMessenger messenger; public event EventHandler? ConnectRequested; public event EventHandler? DisconnectRequested; public bool DisplaysConnected { get { if (this.ConnectDisconnectButtonText == connectedStateButtonText) return true; else if (this.ConnectDisconnectButtonText == disconnectedStateButtonText) return false; else { throw new Exception($"'{nameof(DisplaysConnected)}' has not recognized button text, cannot identify state of connection."); } } } public abstract ProtocolType ProtocolType { get; } [ObservableProperty] private string connectDisconnectButtonText = disconnectedStateButtonText; [ObservableProperty] private bool areEditable = true; // initially editable public ProtocolSettingsViewModel(IMessenger messenger) { this.messenger = messenger; } /// /// Binding to Connect/Disconnect button. /// Button text is provided in /// Implementing class must also implement ! Otherwise does not work. /// [RelayCommand(AllowConcurrentExecutions = false)] private async Task ConnectDisconnectAsync() { await Task.Factory.StartNew(() => { // if currently disconnected if (this.DisplaysConnected == false) { // CONNECT this.AreEditable = false; // create event args. Important: derivative classes must also implement IProtocolSettings! var eventArgs = new ConnectionRequestEventArgs((IProtocolSettings)this); // fire event this.ConnectRequested?.Invoke(this, eventArgs); // after invoke: connection was made successfully? if (eventArgs.Success) { // set button to connected state this.ConnectDisconnectButtonText = connectedStateButtonText; } else { // rollback this.AreEditable = true; } } // if currently connected else { // DISCONNECT this.DisconnectRequested?.Invoke(this, EventArgs.Empty); this.ConnectDisconnectButtonText = disconnectedStateButtonText; this.AreEditable = true; } }); } public void ForceConnectedState(bool connected) { if (connected) { this.ConnectDisconnectButtonText = connectedStateButtonText; this.AreEditable = false; } else { this.ConnectDisconnectButtonText = disconnectedStateButtonText; this.AreEditable = true; } } }