diff --git a/MultiTerm.Core/ViewModel/TerminalViewModel.cs b/MultiTerm.Core/ViewModel/TerminalViewModel.cs
index 44bf8ad..73272d0 100644
--- a/MultiTerm.Core/ViewModel/TerminalViewModel.cs
+++ b/MultiTerm.Core/ViewModel/TerminalViewModel.cs
@@ -26,13 +26,12 @@ public abstract partial class TerminalViewModel : ObservableObject, ITerminalVie
// register event handler for connection request from viewmodel
if(value != null)
{
- protocolSettings!.ConnectRequested += OnViewModelRequestedConnect; ;
+ protocolSettings!.ConnectRequested += OnViewModelRequestedConnect; ; ;
protocolSettings!.DisconnectRequested += OnViewModelRequestedDisconnect;
}
}
}
-
///
/// Method to override if any closing actions are required.
/// Closing can be cancelled using the return value.
@@ -49,13 +48,19 @@ public abstract partial class TerminalViewModel : ObservableObject, ITerminalVie
}
}
- private void OnViewModelRequestedConnect(object? sender, IProtocolSettings e)
+ private void OnViewModelRequestedConnect(object? sender, ConnectionRequestEventArgs e)
{
- this.CommunicationProtocol?.Connect(e);
+ // guard uninitialized CommunicationProtocol
+ if (CommunicationProtocol == null) { throw new Exception($"To call '{nameof(OnViewModelRequestedConnect)}()', CommunicationProtocol must not be null!"); }
+
+ e.Success = this.CommunicationProtocol.Connect(e.Settings);
}
private void OnViewModelRequestedDisconnect(object? sender, EventArgs e)
{
- this.CommunicationProtocol?.Disconnect();
+ // guard uninitialized CommunicationProtocol
+ if (CommunicationProtocol == null) { throw new Exception($"To call '{nameof(OnViewModelRequestedConnect)}()', CommunicationProtocol must not be null!"); }
+
+ this.CommunicationProtocol.Disconnect();
}
}
diff --git a/MultiTerm.Protocols/CommunicationProtocol.cs b/MultiTerm.Protocols/CommunicationProtocol.cs
index b506f67..68b5e27 100644
--- a/MultiTerm.Protocols/CommunicationProtocol.cs
+++ b/MultiTerm.Protocols/CommunicationProtocol.cs
@@ -59,13 +59,13 @@ public abstract class CommunicationProtocol : ICommunicationProtocol
/// cancellation token
protected abstract void InternalRead(CancellationToken ct);
- public void Connect(IProtocolSettings settings)
+ public bool Connect(IProtocolSettings settings)
{
// check if settings are valid, cancel if not
if (settings.AreValid() == false)
{
this.logger.LogError($"'{nameof(Connect)}()' failed since the provided protocol settings are invalid", nameof(CommunicationProtocol));
- return;
+ return false;
}
// try connecting if serttings are valid
@@ -76,10 +76,12 @@ public abstract class CommunicationProtocol : ICommunicationProtocol
// start internal reading thread
this.readingThread = new Thread(() => this.InternalRead(this.cancellationTokenSource.Token));
this.readingThread.Start();
+ return true;
}
else
{
this.logger.LogWarn($"'{nameof(Connect)}()' failed to connect to protocol, did not start reading thread.", nameof(CommunicationProtocol));
+ return false;
}
}
diff --git a/MultiTerm.Protocols/ConnectionRequestEventArgs.cs b/MultiTerm.Protocols/ConnectionRequestEventArgs.cs
new file mode 100644
index 0000000..9247633
--- /dev/null
+++ b/MultiTerm.Protocols/ConnectionRequestEventArgs.cs
@@ -0,0 +1,25 @@
+namespace MultiTerm.Protocols;
+
+public class ConnectionRequestEventArgs : EventArgs
+{
+ ///
+ /// Settings object, contains all settings that are required to connect.
+ ///
+ public IProtocolSettings Settings { get; private set; }
+
+ ///
+ /// Indicates wether the connection could be successfully made.
+ ///
+ public bool Success { get; set; }
+
+ ///
+ /// Creates instance of event args with given .
+ /// Defaults to .
+ ///
+ /// settings object
+ public ConnectionRequestEventArgs(IProtocolSettings settings)
+ {
+ this.Settings = settings;
+ this.Success = true;
+ }
+}
diff --git a/MultiTerm.Protocols/ICommunicationProtocol.cs b/MultiTerm.Protocols/ICommunicationProtocol.cs
index 72a3a90..c0c42f5 100644
--- a/MultiTerm.Protocols/ICommunicationProtocol.cs
+++ b/MultiTerm.Protocols/ICommunicationProtocol.cs
@@ -26,7 +26,7 @@ public interface ICommunicationProtocol
/// Connect to the device.
///
/// settings required to connect and use the protocol
- void Connect(IProtocolSettings settings);
+ bool Connect(IProtocolSettings settings);
///
/// Disconnect from the device. Ends all internal activities.
diff --git a/MultiTerm.Protocols/IProtocolSettingsViewModel.cs b/MultiTerm.Protocols/IProtocolSettingsViewModel.cs
index 4cc1d02..9f61bd5 100644
--- a/MultiTerm.Protocols/IProtocolSettingsViewModel.cs
+++ b/MultiTerm.Protocols/IProtocolSettingsViewModel.cs
@@ -13,7 +13,7 @@ public interface IProtocolSettingsViewModel
/// Event that is thrown when the user requested to connect to the device with the entered settings.
/// Provides protocol settings to use for connection.
///
- event EventHandler ConnectRequested;
+ event EventHandler ConnectRequested;
///
/// Event that is thrown when the user requested to disconnect from the device.
diff --git a/MultiTerm.Protocols/ProtocolSettingsViewModel.cs b/MultiTerm.Protocols/ProtocolSettingsViewModel.cs
index 0474a16..83c7bc1 100644
--- a/MultiTerm.Protocols/ProtocolSettingsViewModel.cs
+++ b/MultiTerm.Protocols/ProtocolSettingsViewModel.cs
@@ -16,7 +16,7 @@ public abstract partial class ProtocolSettingsViewModel : ObservableObject, IPro
private const string disconnectedStateButtonText = "Connect";
protected readonly IMessenger messenger;
- public event EventHandler? ConnectRequested;
+ public event EventHandler? ConnectRequested;
public event EventHandler? DisconnectRequested;
public abstract ProtocolType ProtocolType { get; }
@@ -50,8 +50,23 @@ public abstract partial class ProtocolSettingsViewModel : ObservableObject, IPro
{
// CONNECT
this.AreEditable = false;
- this.ConnectRequested?.Invoke(this, (IProtocolSettings)this); // implementing class must also implement IProtocolSettings!
- this.ConnectDisconnectButtonText = connectedStateButtonText;
+
+ // 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 if (this.ConnectDisconnectButtonText == connectedStateButtonText)