diff --git a/MultiTerm.Core/ViewModel/ITerminalViewModel.cs b/MultiTerm.Core/ViewModel/ITerminalViewModel.cs
index 4902a92..511a5a7 100644
--- a/MultiTerm.Core/ViewModel/ITerminalViewModel.cs
+++ b/MultiTerm.Core/ViewModel/ITerminalViewModel.cs
@@ -1,8 +1,19 @@
-using System;
-
-namespace MultiTerm.Core.ViewModel;
+namespace MultiTerm.Core.ViewModel;
public interface ITerminalViewModel
{
+ ///
+ /// Title of the Terminal View.
+ ///
string Title { get; }
+
+ ///
+ /// Request Closing of Terminal.
+ ///
+ void CloseRequest();
+
+ ///
+ /// Closing of Terminal was initiated.
+ ///
+ event EventHandler ClosingEvent;
}
diff --git a/MultiTerm.Core/ViewModel/SendReceiveViewModel.cs b/MultiTerm.Core/ViewModel/SendReceiveViewModel.cs
index 7e4b60a..6bb8d5f 100644
--- a/MultiTerm.Core/ViewModel/SendReceiveViewModel.cs
+++ b/MultiTerm.Core/ViewModel/SendReceiveViewModel.cs
@@ -1,10 +1,7 @@
-using System;
-using CommunityToolkit.Mvvm.ComponentModel;
+namespace MultiTerm.Core.ViewModel;
-namespace MultiTerm.Core.ViewModel;
-
-[ObservableObject]
public partial class SendReceiveViewModel : TerminalViewModel
{
public override string Title => "SendReceive Tab";
+
}
diff --git a/MultiTerm.Core/ViewModel/ShellViewModel.cs b/MultiTerm.Core/ViewModel/ShellViewModel.cs
index 410e90b..c6ac700 100644
--- a/MultiTerm.Core/ViewModel/ShellViewModel.cs
+++ b/MultiTerm.Core/ViewModel/ShellViewModel.cs
@@ -39,15 +39,29 @@ public partial class ShellViewModel : ObservableObject
public void AppendTerminal(ITerminalViewModel newTerminal)
{
// guard null value
- if(newTerminal == null)
- {
- return;
- }
- // add to collection and set as selected
+ if(newTerminal == null) { return; }
+
+ // add to collection and register closing event handler
this.TerminalViewModels.Add(newTerminal);
+ newTerminal.ClosingEvent += Terminal_ClosingEvent;
+ // set as selected
this.SelectedTerminalViewModel = newTerminal;
}
+ private void Terminal_ClosingEvent(object? sender, EventArgs e)
+ {
+ if(sender is not ITerminalViewModel tvm) { throw new ArgumentException(nameof(sender)); }
+ this.RemoveTerminal(tvm);
+ }
+
+ public void RemoveTerminal(ITerminalViewModel terminalToRemove)
+ {
+ // guard null value
+ if(terminalToRemove == null) { return; }
+
+ this.TerminalViewModels.Remove(terminalToRemove);
+ }
+
partial void OnDefaultReceiveNewlineSeparatorChanged(NewlineSeparatorType value)
{
Console.WriteLine($"Changed to {value}");
diff --git a/MultiTerm.Core/ViewModel/TerminalViewModel.cs b/MultiTerm.Core/ViewModel/TerminalViewModel.cs
index 08feb2d..36ab34c 100644
--- a/MultiTerm.Core/ViewModel/TerminalViewModel.cs
+++ b/MultiTerm.Core/ViewModel/TerminalViewModel.cs
@@ -1,8 +1,27 @@
-using System;
+using CommunityToolkit.Mvvm.ComponentModel;
+using CommunityToolkit.Mvvm.Input;
namespace MultiTerm.Core.ViewModel;
-public abstract class TerminalViewModel : ITerminalViewModel
+public abstract partial class TerminalViewModel : ObservableObject, ITerminalViewModel
{
public abstract string Title { get; }
+
+ public event EventHandler? ClosingEvent;
+
+ ///
+ /// Method to override if any closing actions are required.
+ /// Closing can be cancelled using the return value.
+ ///
+ /// true if closing is allowed. false if it shall be cancelled.
+ protected virtual bool ClosingActions() { return true; }
+
+ [RelayCommand]
+ public void CloseRequest()
+ {
+ if (this.ClosingActions() == true)
+ {
+ ClosingEvent?.Invoke(this, EventArgs.Empty);
+ }
+ }
}
diff --git a/MultiTerm.Wpf/View/ShellView.xaml b/MultiTerm.Wpf/View/ShellView.xaml
index d9b06c7..dbe05a6 100644
--- a/MultiTerm.Wpf/View/ShellView.xaml
+++ b/MultiTerm.Wpf/View/ShellView.xaml
@@ -57,23 +57,36 @@
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
-
-
-
-