diff --git a/MultiTerm.Core/Common/ProtocolType.cs b/MultiTerm.Core/Common/ProtocolType.cs
new file mode 100644
index 0000000..ae241e8
--- /dev/null
+++ b/MultiTerm.Core/Common/ProtocolType.cs
@@ -0,0 +1,30 @@
+using System.ComponentModel;
+
+namespace MultiTerm.Core.Common;
+
+public enum ProtocolType
+{
+ ///
+ /// Serial Protocol
+ ///
+ [Description("Serial")]
+ Serial,
+
+ ///
+ /// USB HID Protocol
+ ///
+ [Description("USB HID")]
+ UsbHid,
+
+ ///
+ /// TCP Protocol
+ ///
+ [Description("TCP")]
+ Tcp,
+
+ ///
+ /// UDP Protocol
+ ///
+ [Description("UCP")]
+ Udp
+}
diff --git a/MultiTerm.Core/Common/TerminalViewType.cs b/MultiTerm.Core/Common/TerminalViewType.cs
new file mode 100644
index 0000000..66445d9
--- /dev/null
+++ b/MultiTerm.Core/Common/TerminalViewType.cs
@@ -0,0 +1,18 @@
+using System.ComponentModel;
+
+namespace MultiTerm.Core.Common;
+
+public enum TerminalViewType
+{
+ ///
+ /// SendReceive View
+ ///
+ [Description("Send/Receive")]
+ SendReceive,
+
+ ///
+ /// Console View
+ ///
+ [Description("Console")]
+ Console
+}
diff --git a/MultiTerm.Core/ViewModel/ITerminalViewModel.cs b/MultiTerm.Core/ViewModel/ITerminalViewModel.cs
index 511a5a7..52db3f6 100644
--- a/MultiTerm.Core/ViewModel/ITerminalViewModel.cs
+++ b/MultiTerm.Core/ViewModel/ITerminalViewModel.cs
@@ -1,4 +1,6 @@
-namespace MultiTerm.Core.ViewModel;
+using MultiTerm.Core.Common;
+
+namespace MultiTerm.Core.ViewModel;
public interface ITerminalViewModel
{
@@ -6,6 +8,16 @@ public interface ITerminalViewModel
/// Title of the Terminal View.
///
string Title { get; }
+
+ ///
+ /// Type of view.
+ ///
+ TerminalViewType ViewType { get; }
+
+ ///
+ /// Type of Protocol.
+ ///
+ ProtocolType ProtocolType { get; }
///
/// Request Closing of Terminal.
diff --git a/MultiTerm.Core/ViewModel/SendReceiveViewModel.cs b/MultiTerm.Core/ViewModel/SendReceiveViewModel.cs
index 6bb8d5f..feb9da8 100644
--- a/MultiTerm.Core/ViewModel/SendReceiveViewModel.cs
+++ b/MultiTerm.Core/ViewModel/SendReceiveViewModel.cs
@@ -1,7 +1,15 @@
-namespace MultiTerm.Core.ViewModel;
+using MultiTerm.Core.Common;
+
+namespace MultiTerm.Core.ViewModel;
public partial class SendReceiveViewModel : TerminalViewModel
{
public override string Title => "SendReceive Tab";
+ public override TerminalViewType ViewType => TerminalViewType.SendReceive;
+
+ public SendReceiveViewModel() : base(ProtocolType.Serial) // TODO implement Protocol initialization
+ {
+
+ }
}
diff --git a/MultiTerm.Core/ViewModel/ShellViewModel.cs b/MultiTerm.Core/ViewModel/ShellViewModel.cs
index c6ac700..4c753ca 100644
--- a/MultiTerm.Core/ViewModel/ShellViewModel.cs
+++ b/MultiTerm.Core/ViewModel/ShellViewModel.cs
@@ -29,6 +29,12 @@ public partial class ShellViewModel : ObservableObject
private NewlineSeparatorType defaultSendNewlineSeparator = NewlineSeparatorType.None;
#endregion
+ #region New Terminal Context Menu
+ [ObservableProperty]
+ private TerminalViewType selectedTerminalViewType = TerminalViewType.SendReceive;
+
+ #endregion
+
public ShellViewModel(IAbstractFactory sendReceiveViewModelFactory)
{
this.sendReceiveViewModelFactory = sendReceiveViewModelFactory;
@@ -36,7 +42,8 @@ public partial class ShellViewModel : ObservableObject
this.AppendTerminal(this.sendReceiveViewModelFactory.Create());
}
- public void AppendTerminal(ITerminalViewModel newTerminal)
+ [RelayCommand]
+ private void AppendTerminal(ITerminalViewModel? newTerminal)
{
// guard null value
if(newTerminal == null) { return; }
@@ -50,11 +57,11 @@ public partial class ShellViewModel : ObservableObject
private void Terminal_ClosingEvent(object? sender, EventArgs e)
{
- if(sender is not ITerminalViewModel tvm) { throw new ArgumentException(nameof(sender)); }
+ if(sender is not ITerminalViewModel tvm) { throw new ArgumentException($"{nameof(Terminal_ClosingEvent)} failed to convert sender to {nameof(ITerminalViewModel)}"); }
this.RemoveTerminal(tvm);
}
- public void RemoveTerminal(ITerminalViewModel terminalToRemove)
+ private void RemoveTerminal(ITerminalViewModel terminalToRemove)
{
// guard null value
if(terminalToRemove == null) { return; }
@@ -73,7 +80,7 @@ public partial class ShellViewModel : ObservableObject
}
[RelayCommand]
- public void TestButtonClicked()
+ private void TestButtonClicked()
{
this.DefaultReceiveNewlineSeparator = NewlineSeparatorType.CR_LF;
}
diff --git a/MultiTerm.Core/ViewModel/TerminalViewModel.cs b/MultiTerm.Core/ViewModel/TerminalViewModel.cs
index 36ab34c..14a84cd 100644
--- a/MultiTerm.Core/ViewModel/TerminalViewModel.cs
+++ b/MultiTerm.Core/ViewModel/TerminalViewModel.cs
@@ -1,14 +1,22 @@
using CommunityToolkit.Mvvm.ComponentModel;
using CommunityToolkit.Mvvm.Input;
+using MultiTerm.Core.Common;
namespace MultiTerm.Core.ViewModel;
public abstract partial class TerminalViewModel : ObservableObject, ITerminalViewModel
{
public abstract string Title { get; }
+ public abstract TerminalViewType ViewType { get; }
+ public ProtocolType ProtocolType { get; private set; }
public event EventHandler? ClosingEvent;
+ public TerminalViewModel(ProtocolType protocolType)
+ {
+ this.ProtocolType = protocolType;
+ }
+
///
/// Method to override if any closing actions are required.
/// Closing can be cancelled using the return value.
diff --git a/MultiTerm.Wpf/App.xaml.cs b/MultiTerm.Wpf/App.xaml.cs
index 406f307..ea899db 100644
--- a/MultiTerm.Wpf/App.xaml.cs
+++ b/MultiTerm.Wpf/App.xaml.cs
@@ -3,6 +3,7 @@ using Microsoft.Extensions.Hosting;
using MultiTerm.Core.ViewModel;
using Common.StartupHelpers;
using System.Windows;
+using MultiTerm.Core.Common;
namespace MultiTerm.Wpf;
diff --git a/MultiTerm.Wpf/Controls/SingleSelectSubMenu.cs b/MultiTerm.Wpf/Controls/SingleSelectSubMenu.cs
index f9f82f4..ea08567 100644
--- a/MultiTerm.Wpf/Controls/SingleSelectSubMenu.cs
+++ b/MultiTerm.Wpf/Controls/SingleSelectSubMenu.cs
@@ -105,7 +105,7 @@ public class SingleSelectSubMenu : MenuItem
///
/// Options Source Changed Handler.
- /// Builds list with options and adds them to parent MenuItem (must be Menu Item!).
+ /// Builds list with options and adds them to parent ItemsControl (must be subtype of ItemsControl).
/// Registers menu Items in locally stored list.
/// Cannot handle changing OptionsSources. Internal list will build up.
///
@@ -114,7 +114,7 @@ public class SingleSelectSubMenu : MenuItem
// extract instance and guard null
if (d is not SingleSelectSubMenu sssm) { return; }
// extract parent instance of SSSM and guard null
- if (sssm.Parent is not MenuItem parent) { return; }
+ if (sssm.Parent is not ItemsControl parent) { throw new ArgumentException($"Wrong parent type."); }
// iterate through new OptionsSource Values and build up list of menuItems
foreach (var item in (IEnumerable)e.NewValue)
@@ -123,6 +123,7 @@ public class SingleSelectSubMenu : MenuItem
var converter = new EnumDescriptionToMenuItemConverter();
var newMenuItem = (MenuItem)converter.Convert(item, typeof(MenuItem), new object(), CultureInfo.CurrentCulture);
newMenuItem.IsCheckable = true;
+ newMenuItem.StaysOpenOnClick = true;
// assign to event handler and register in dictionary
newMenuItem.Checked += OnAnyItemChecked;
diff --git a/MultiTerm.Wpf/Helpers/BindingProxy.cs b/MultiTerm.Wpf/Helpers/BindingProxy.cs
new file mode 100644
index 0000000..f04196b
--- /dev/null
+++ b/MultiTerm.Wpf/Helpers/BindingProxy.cs
@@ -0,0 +1,27 @@
+using System.Windows;
+
+namespace MultiTerm.Wpf.Helpers;
+
+///
+/// Serves as a Proxy to provide DataContext for Elements that are not part of the VisualTree.
+/// From: https://thomaslevesque.com/2011/03/21/wpf-how-to-bind-to-data-when-the-datacontext-is-not-inherited/
+///
+public class BindingProxy : Freezable
+{
+ #region Overrides of Freezable
+ protected override Freezable CreateInstanceCore()
+ {
+ return new BindingProxy();
+ }
+ #endregion
+
+ public object Data
+ {
+ get { return (object)GetValue(DataProperty); }
+ set { SetValue(DataProperty, value); }
+ }
+
+ // Using a DependencyProperty as the backing store for Data. This enables animation, styling, binding, etc...
+ public static readonly DependencyProperty DataProperty =
+ DependencyProperty.Register("Data", typeof(object), typeof(BindingProxy), new UIPropertyMetadata(null));
+}
diff --git a/MultiTerm.Wpf/View/ShellView.xaml b/MultiTerm.Wpf/View/ShellView.xaml
index dbe05a6..d45afb3 100644
--- a/MultiTerm.Wpf/View/ShellView.xaml
+++ b/MultiTerm.Wpf/View/ShellView.xaml
@@ -9,6 +9,7 @@
xmlns:vm="clr-namespace:MultiTerm.Core.ViewModel;assembly=MultiTerm.Core"
xmlns:v="clr-namespace:MultiTerm.Wpf.View"
xmlns:core_common="clr-namespace:MultiTerm.Core.Common;assembly=MultiTerm.Core"
+ xmlns:helpers="clr-namespace:MultiTerm.Wpf.Helpers"
mc:Ignorable="d"
d:DesignHeight="600" d:DesignWidth="1200">
@@ -23,6 +24,13 @@
+
+
+
+
+
@@ -51,14 +59,68 @@
+ SelectedMenuItem="{Binding DefaultSendNewlineSeparator, Mode=TwoWay, Converter={StaticResource EnumDescriptionConverter}}">
+
+