From 12a3b6792f2a788014179fc1a446683ad059fcf0 Mon Sep 17 00:00:00 2001 From: Jonas Arnold Date: Fri, 12 May 2023 10:39:36 +0200 Subject: [PATCH] implemented progress bar and auto remove status bar message after duration, moved TabContent to Wpf Project instead of CustomControl Project, added ProgressBarSmoother, fixed exception in destructor of MultiFormatTextBox, added message on unintentional disconnect, added detection in TCP when socket was closed --- MultiTerm.Core/ViewModel/ShellViewModel.cs | 40 +++++++++++++++++++ MultiTerm.Protocols/CommunicationProtocol.cs | 3 ++ MultiTerm.Protocols/Tcp/TcpClientProtocol.cs | 8 ++++ .../MultiFormatTextBox/MultiFormatTextBox.cs | 6 ++- .../MultiTerm.Wpf.CustomControl.csproj | 4 -- .../Behaviours/ProgressBarSmoother.cs | 38 ++++++++++++++++++ .../Behaviours/TabContent.cs | 2 +- MultiTerm.Wpf/View/ShellView.xaml | 18 ++++++--- 8 files changed, 107 insertions(+), 12 deletions(-) create mode 100644 MultiTerm.Wpf/Behaviours/ProgressBarSmoother.cs rename {MultiTerm.Wpf.CustomControl => MultiTerm.Wpf}/Behaviours/TabContent.cs (99%) diff --git a/MultiTerm.Core/ViewModel/ShellViewModel.cs b/MultiTerm.Core/ViewModel/ShellViewModel.cs index a65d4c1..49c85b0 100644 --- a/MultiTerm.Core/ViewModel/ShellViewModel.cs +++ b/MultiTerm.Core/ViewModel/ShellViewModel.cs @@ -9,6 +9,7 @@ using MultiTerm.Core.Types; using MultiTerm.Protocols.Types; using CommunityToolkit.Mvvm.Messaging; using Common.Messaging; +using System.Timers; namespace MultiTerm.Core.ViewModel; @@ -16,6 +17,7 @@ public partial class ShellViewModel : ObservableObject, IRecipient 0) + { + this.StatusBarMessageDurationPercentage -= differencePercentage; + return; + } + + // clear message and kill timer when finished + this.StatusBarMessage = ""; + this.StatusBarMessageDurationPercentage = 0; + this.statusBarMessageTimer!.Enabled = false; + this.statusBarMessageTimer.Dispose(); + this.statusBarMessageTimer = null; } #endregion } diff --git a/MultiTerm.Protocols/CommunicationProtocol.cs b/MultiTerm.Protocols/CommunicationProtocol.cs index a4b1c9b..8d92cad 100644 --- a/MultiTerm.Protocols/CommunicationProtocol.cs +++ b/MultiTerm.Protocols/CommunicationProtocol.cs @@ -68,6 +68,9 @@ public abstract class CommunicationProtocol : ICommunicationProtocol // update state this.State = ProtocolConnectionState.UnintentionallyDisconnected; + + // inform user + this.messenger.Send(new GenericUserInterfaceMessage($"'{this.GetProtocolAndInstanceIdentifier()}' unintentionally disconnected.", MessageImportance.High)); }); } diff --git a/MultiTerm.Protocols/Tcp/TcpClientProtocol.cs b/MultiTerm.Protocols/Tcp/TcpClientProtocol.cs index dd3d7ec..f24b6b9 100644 --- a/MultiTerm.Protocols/Tcp/TcpClientProtocol.cs +++ b/MultiTerm.Protocols/Tcp/TcpClientProtocol.cs @@ -105,6 +105,14 @@ public class TcpClientProtocol : CommunicationProtocol { while (ct.IsCancellationRequested == false) { + // check if client still connected + if (this.client == null || this.client?.Connected == false) + { + this.logger.LogError($"Client isnull={this.client == null} or not connected anymore while sending data in {nameof(InternalRead)}", nameof(TcpClientProtocol)); + this.OnUnintentionallyDisconnected(); + break; // break loop + } + // try receive message with a buffer int readByte = -1; try diff --git a/MultiTerm.Wpf.CustomControl/MultiFormatTextBox/MultiFormatTextBox.cs b/MultiTerm.Wpf.CustomControl/MultiFormatTextBox/MultiFormatTextBox.cs index b25b70d..e44b8af 100644 --- a/MultiTerm.Wpf.CustomControl/MultiFormatTextBox/MultiFormatTextBox.cs +++ b/MultiTerm.Wpf.CustomControl/MultiFormatTextBox/MultiFormatTextBox.cs @@ -83,8 +83,10 @@ public class MultiFormatTextBox : Control ~MultiFormatTextBox() { // unregister events - var incc = this.CurrentMultiFormatString as INotifyCollectionChanged; - incc.CollectionChanged -= this.MultiFormatString_CollectionChanged; + if (this.CurrentMultiFormatString is INotifyCollectionChanged incc) + { + incc.CollectionChanged -= this.MultiFormatString_CollectionChanged; + } } public override void OnApplyTemplate() diff --git a/MultiTerm.Wpf.CustomControl/MultiTerm.Wpf.CustomControl.csproj b/MultiTerm.Wpf.CustomControl/MultiTerm.Wpf.CustomControl.csproj index b8f9a24..e29b1fc 100644 --- a/MultiTerm.Wpf.CustomControl/MultiTerm.Wpf.CustomControl.csproj +++ b/MultiTerm.Wpf.CustomControl/MultiTerm.Wpf.CustomControl.csproj @@ -14,8 +14,4 @@ - - - - diff --git a/MultiTerm.Wpf/Behaviours/ProgressBarSmoother.cs b/MultiTerm.Wpf/Behaviours/ProgressBarSmoother.cs new file mode 100644 index 0000000..00e8dbb --- /dev/null +++ b/MultiTerm.Wpf/Behaviours/ProgressBarSmoother.cs @@ -0,0 +1,38 @@ +using System; +using System.Windows.Controls; +using System.Windows.Media.Animation; +using System.Windows; + +namespace MultiTerm.Wpf.Behaviours; + +/// +/// From https://stackoverflow.com/questions/14485818/how-to-update-a-progress-bar-so-it-increases-smoothly +/// +public class ProgressBarSmoother +{ + public static double GetSmoothValue(DependencyObject obj) + { + return (double)obj.GetValue(SmoothValueProperty); + } + + public static void SetSmoothValue(DependencyObject obj, double value) + { + obj.SetValue(SmoothValueProperty, value); + } + + public static readonly DependencyProperty SmoothValueProperty = + DependencyProperty.RegisterAttached( + "SmoothValue", + typeof(double), + typeof(ProgressBarSmoother), + new PropertyMetadata(0.0, Changing)); + + private static void Changing(DependencyObject d, DependencyPropertyChangedEventArgs e) + { + // guard wrong type + if(d is not ProgressBar progressBar) { return; } + + var anim = new DoubleAnimation((double)e.OldValue, (double)e.NewValue, new TimeSpan(0, 0, 0, 0, 250)); + progressBar.BeginAnimation(ProgressBar.ValueProperty, anim, HandoffBehavior.Compose); + } +} diff --git a/MultiTerm.Wpf.CustomControl/Behaviours/TabContent.cs b/MultiTerm.Wpf/Behaviours/TabContent.cs similarity index 99% rename from MultiTerm.Wpf.CustomControl/Behaviours/TabContent.cs rename to MultiTerm.Wpf/Behaviours/TabContent.cs index ee6b3c2..c1e57c5 100644 --- a/MultiTerm.Wpf.CustomControl/Behaviours/TabContent.cs +++ b/MultiTerm.Wpf/Behaviours/TabContent.cs @@ -9,7 +9,7 @@ using System.Windows.Controls; using System.Windows.Data; using System.Windows.Markup; -namespace MultiTerm.Wpf.CustomControl; +namespace MultiTerm.Wpf.Behaviours; /// /// Attached properties for persistent tab control diff --git a/MultiTerm.Wpf/View/ShellView.xaml b/MultiTerm.Wpf/View/ShellView.xaml index 53ddcd7..7657cfd 100644 --- a/MultiTerm.Wpf/View/ShellView.xaml +++ b/MultiTerm.Wpf/View/ShellView.xaml @@ -9,6 +9,7 @@ xmlns:custom_controls="clr-namespace:MultiTerm.Wpf.CustomControl;assembly=MultiTerm.Wpf.CustomControl" xmlns:vm="clr-namespace:MultiTerm.Core.ViewModel;assembly=MultiTerm.Core" xmlns:v="clr-namespace:MultiTerm.Wpf.View" + xmlns:behaviours="clr-namespace:MultiTerm.Wpf.Behaviours" xmlns:types="clr-namespace:MultiTerm.Core.Types;assembly=MultiTerm.Core" xmlns:protocol_types="clr-namespace:MultiTerm.Protocols.Types;assembly=MultiTerm.Protocols" xmlns:helpers="clr-namespace:MultiTerm.Wpf.Helpers" @@ -76,9 +77,16 @@ - + - + + + + @@ -132,7 +140,7 @@ @@ -144,11 +152,11 @@ - + - +