From 0210de0c2bf8bbf77ab5a5d1bb15a2bb54e30ffc Mon Sep 17 00:00:00 2001 From: Jonas Arnold Date: Thu, 20 Apr 2023 10:27:33 +0200 Subject: [PATCH] introduced DataViewModel to wrap ExtendedChar Model and create line identifier, changed MultiFormatDataView to VirtualizingWrapPanel and added grouping per line --- .../ViewModel/CommunicationDataViewModel.cs | 20 ++++---- MultiTerm.Core/ViewModel/DataViewModel.cs | 47 +++++++++++++++++++ MultiTerm.Protocols/Model/DataLine.cs | 28 ----------- MultiTerm.Protocols/Model/ExtendedChar.cs | 23 +-------- .../MultiFormatDataView.cs | 28 +++++++++-- .../MultiFormatDataView.xaml | 46 +++++++----------- MultiTerm.Wpf/View/SendReceiveView.xaml | 4 +- 7 files changed, 102 insertions(+), 94 deletions(-) create mode 100644 MultiTerm.Core/ViewModel/DataViewModel.cs delete mode 100644 MultiTerm.Protocols/Model/DataLine.cs diff --git a/MultiTerm.Core/ViewModel/CommunicationDataViewModel.cs b/MultiTerm.Core/ViewModel/CommunicationDataViewModel.cs index 07e2bba..ef2fed2 100644 --- a/MultiTerm.Core/ViewModel/CommunicationDataViewModel.cs +++ b/MultiTerm.Core/ViewModel/CommunicationDataViewModel.cs @@ -14,7 +14,7 @@ public partial class CommunicationDataViewModel : ObservableObject /// Represents the collection of received characters from a communicaiton protocol. /// [ObservableProperty] - private ObservableCollection receivedData = new(); + private ObservableCollection receivedData = new(); /// /// Represents the collection of received characters from a communicaiton protocol. @@ -38,22 +38,24 @@ public partial class CommunicationDataViewModel : ObservableObject } else // TEMP { - string lorem = "Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Pellentesque elit eget gravida cum sociis natoque penatibus et magnis. Purus sit amet volutpat consequat mauris nunc congue nisi vitae. Id ornare arcu odio ut sem. Neque ornare aenean euismod elementum nisi quis eleifend. Faucibus vitae aliquet nec ullamcorper sit. Fermentum iaculis eu non diam phasellus vestibulum lorem sed risus. Pellentesque nec nam aliquam sem et tortor consequat id porta. Diam sollicitudin tempor id eu nisl. Fames ac turpis egestas sed tempus urna et. Commodo odio aenean sed adipiscing diam donec adipiscing tristique risus. Id aliquet lectus proin nibh nisl condimentum id. Dolor sit amet consectetur adipiscing elit duis. Sed vulputate odio ut enim blandit. Neque convallis a cras semper auctor neque vitae.\r\n\r\nLacus laoreet non curabitur gravida arcu ac tortor. Volutpat maecenas volutpat blandit aliquam. Neque laoreet suspendisse interdum consectetur. Tincidunt augue interdum velit euismod in pellentesque massa placerat. Magna fringilla urna porttitor rhoncus dolor purus non enim praesent. Fermentum leo vel orci porta non pulvinar neque laoreet suspendisse. Scelerisque viverra mauris in aliquam sem fringilla. Nec feugiat nisl pretium fusce id velit ut. Urna cursus eget nunc scelerisque viverra mauris. Condimentum mattis pellentesque id nibh tortor id aliquet. Enim sed faucibus turpis in eu. Adipiscing elit pellentesque habitant morbi tristique. A pellentesque sit amet porttitor eget dolor morbi non arcu. Amet commodo nulla facilisi nullam vehicula ipsum a arcu. Hac habitasse platea dictumst vestibulum rhoncus est pellentesque elit ullamcorper. Curabitur vitae nunc sed velit dignissim sodales ut. Malesuada fames ac turpis egestas maecenas pharetra. Tellus pellentesque eu tincidunt tortor aliquam.\r\n\r\nVitae proin sagittis nisl rhoncus mattis rhoncus urna neque viverra. Eget mi proin sed libero enim sed faucibus. Commodo nulla facilisi nullam vehicula ipsum. Proin libero nunc consequat interdum varius sit amet mattis vulputate. Morbi tristique senectus et netus. Feugiat scelerisque varius morbi enim nunc. Nulla aliquet enim tortor at auctor urna nunc. Non pulvinar neque laoreet suspendisse interdum consectetur libero id. Tellus orci ac auctor augue mauris augue neque gravida in. In egestas erat imperdiet sed euismod. Amet volutpat consequat mauris nunc congue nisi. Massa eget egestas purus viverra accumsan in. Eget duis at tellus at. Mi sit amet mauris commodo quis imperdiet. Nibh mauris cursus mattis molestie a iaculis at.\r\n\r\nNetus et malesuada fames ac turpis. Sit amet dictum sit amet justo donec. Euismod quis viverra nibh cras pulvinar mattis. Sit amet commodo nulla facilisi nullam vehicula ipsum a arcu. Scelerisque felis imperdiet proin fermentum. Ac tincidunt vitae semper quis lectus nulla at. Sit amet commodo nulla facilisi nullam vehicula. Enim lobortis scelerisque fermentum dui faucibus in ornare quam. Quam id leo in vitae turpis massa sed. Quam quisque id diam vel quam. A condimentum vitae sapien pellentesque. Neque aliquam vestibulum morbi blandit cursus risus at. Velit laoreet id donec ultrices tincidunt arcu non sodales neque. Tempus imperdiet nulla malesuada pellentesque elit eget gravida cum sociis. Egestas tellus rutrum tellus pellentesque eu tincidunt tortor. Nec feugiat in fermentum posuere. Dui accumsan sit amet nulla. Lacus viverra vitae congue eu consequat ac felis. Etiam tempor orci eu lobortis. Fermentum leo vel orci porta non pulvinar."; - string mcu = "<\\r><\\n>\r\n--------------------------------------------------------------<\\r><\\n>\r\nSPLITFLAP<\\r><\\n>\r\n--------------------------------------------------------------<\\r><\\n>\r\nMcuShell ; Group of McuShell commands<\\r><\\n>\r\n help|status ; Print help or status information<\\r><\\n>\r\nSplitFlap ; Group of McuRTOS commands<\\r><\\n>\r\n help ; Print help or status information<\\r><\\n>\r\n setId ; sets the position (setupId) of the sf and its id (hwId)<\\r><\\n>\r\n initAll ; init all Splitflaps<\\r><\\n>\r\n Display ; displays as many chars of the string as sf are available<\\r><\\n>\r\n addId ; add new hwId with offset<\\r><\\n>\r\nMcuRTOS ; Group of McuRTOS commands<\\r><\\n>\r\n help|status ; Print help or status information<\\r><\\n>\r\n tasklist ; Print tasklist<\\r><\\n>\r\nMcuFlash ; Group of flash ini commands<\\r><\\n>\r\n help|status ; Print help or status information<\\r><\\n>\r\n dump ; Dump memory data<\\r><\\n>\r\n erase ; Erase memory at address<\\r><\\n>\r\nini ; Group of flash ini commands<\\r><\\n>\r\n help|status ; Print help or status information<\\r><\\n>\r\n dump ; Dump data information<\\r><\\n>\r\n erase ; Erase data information<\\r><\\n>\r\nMcuMinINI ; Group of McuMinINI commands<\\r><\\n>\r\n help|status ; Print help or status information<\\r><\\n>\r\n read ; Read a key from a section in a file<\\r><\\n>\r\n write ; Write a key with value to a section in a file<\\r><\\n>\r\n delkey ; Delete a key in a section of file<\\r><\\n>\r\n delsec ; Delete a section in a file<\\r><\\n>\r\nnvmc ; Group of NVMC commands<\\r><\\n>\r\n help|status ; Print help or status information<\\r><\\n>\r\n flags ; Set flags<\\r><\\n>\r\nrs ; Group of RS-485 commands<\\r><\\n>\r\n help|status ; Print help or status information<\\r><\\n>\r\n addr ; Set RS-485 address<\\r><\\n>\r\n send ; Send a text to the RS-485 bus<\\r><\\n>\r\n sendcmd ; Send a shell command to the RS-485 address and check response<\\r><\\n>\r\n log on|off ; Log RS-485 bus activity to McuLog<\\r><\\n>\r\nMcuUart485 ; Group of RS-485 commands<\\r><\\n>\r\n help|status ; Print help or status information<\\r><\\n>\r\n clear ; Clear UART ISR flags<\\r><\\n>\r\n<\\r><\\n>\r\nCMD>"; + //string exampleData = "Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Pellentesque elit eget gravida cum sociis natoque penatibus et magnis. Purus sit amet volutpat consequat mauris nunc congue nisi vitae. Id ornare arcu odio ut sem. Neque ornare aenean euismod elementum nisi quis eleifend. Faucibus vitae aliquet nec ullamcorper sit. Fermentum iaculis eu non diam phasellus vestibulum lorem sed risus. Pellentesque nec nam aliquam sem et tortor consequat id porta. Diam sollicitudin tempor id eu nisl. Fames ac turpis egestas sed tempus urna et. Commodo odio aenean sed adipiscing diam donec adipiscing tristique risus. Id aliquet lectus proin nibh nisl condimentum id. Dolor sit amet consectetur adipiscing elit duis. Sed vulputate odio ut enim blandit. Neque convallis a cras semper auctor neque vitae.\r\n\r\nLacus laoreet non curabitur gravida arcu ac tortor. Volutpat maecenas volutpat blandit aliquam. Neque laoreet suspendisse interdum consectetur. Tincidunt augue interdum velit euismod in pellentesque massa placerat. Magna fringilla urna porttitor rhoncus dolor purus non enim praesent. Fermentum leo vel orci porta non pulvinar neque laoreet suspendisse. Scelerisque viverra mauris in aliquam sem fringilla. Nec feugiat nisl pretium fusce id velit ut. Urna cursus eget nunc scelerisque viverra mauris. Condimentum mattis pellentesque id nibh tortor id aliquet. Enim sed faucibus turpis in eu. Adipiscing elit pellentesque habitant morbi tristique. A pellentesque sit amet porttitor eget dolor morbi non arcu. Amet commodo nulla facilisi nullam vehicula ipsum a arcu. Hac habitasse platea dictumst vestibulum rhoncus est pellentesque elit ullamcorper. Curabitur vitae nunc sed velit dignissim sodales ut. Malesuada fames ac turpis egestas maecenas pharetra. Tellus pellentesque eu tincidunt tortor aliquam.\r\n\r\nVitae proin sagittis nisl rhoncus mattis rhoncus urna neque viverra. Eget mi proin sed libero enim sed faucibus. Commodo nulla facilisi nullam vehicula ipsum. Proin libero nunc consequat interdum varius sit amet mattis vulputate. Morbi tristique senectus et netus. Feugiat scelerisque varius morbi enim nunc. Nulla aliquet enim tortor at auctor urna nunc. Non pulvinar neque laoreet suspendisse interdum consectetur libero id. Tellus orci ac auctor augue mauris augue neque gravida in. In egestas erat imperdiet sed euismod. Amet volutpat consequat mauris nunc congue nisi. Massa eget egestas purus viverra accumsan in. Eget duis at tellus at. Mi sit amet mauris commodo quis imperdiet. Nibh mauris cursus mattis molestie a iaculis at.\r\n\r\nNetus et malesuada fames ac turpis. Sit amet dictum sit amet justo donec. Euismod quis viverra nibh cras pulvinar mattis. Sit amet commodo nulla facilisi nullam vehicula ipsum a arcu. Scelerisque felis imperdiet proin fermentum. Ac tincidunt vitae semper quis lectus nulla at. Sit amet commodo nulla facilisi nullam vehicula. Enim lobortis scelerisque fermentum dui faucibus in ornare quam. Quam id leo in vitae turpis massa sed. Quam quisque id diam vel quam. A condimentum vitae sapien pellentesque. Neque aliquam vestibulum morbi blandit cursus risus at. Velit laoreet id donec ultrices tincidunt arcu non sodales neque. Tempus imperdiet nulla malesuada pellentesque elit eget gravida cum sociis. Egestas tellus rutrum tellus pellentesque eu tincidunt tortor. Nec feugiat in fermentum posuere. Dui accumsan sit amet nulla. Lacus viverra vitae congue eu consequat ac felis. Etiam tempor orci eu lobortis. Fermentum leo vel orci porta non pulvinar."; + //string exampleData = "<\\r><\\n>\r\n--------------------------------------------------------------<\\r><\\n>\r\nSPLITFLAP<\\r><\\n>\r\n--------------------------------------------------------------<\\r><\\n>\r\nMcuShell ; Group of McuShell commands<\\r><\\n>\r\n help|status ; Print help or status information<\\r><\\n>\r\nSplitFlap ; Group of McuRTOS commands<\\r><\\n>\r\n help ; Print help or status information<\\r><\\n>\r\n setId ; sets the position (setupId) of the sf and its id (hwId)<\\r><\\n>\r\n initAll ; init all Splitflaps<\\r><\\n>\r\n Display ; displays as many chars of the string as sf are available<\\r><\\n>\r\n addId ; add new hwId with offset<\\r><\\n>\r\nMcuRTOS ; Group of McuRTOS commands<\\r><\\n>\r\n help|status ; Print help or status information<\\r><\\n>\r\n tasklist ; Print tasklist<\\r><\\n>\r\nMcuFlash ; Group of flash ini commands<\\r><\\n>\r\n help|status ; Print help or status information<\\r><\\n>\r\n dump ; Dump memory data<\\r><\\n>\r\n erase ; Erase memory at address<\\r><\\n>\r\nini ; Group of flash ini commands<\\r><\\n>\r\n help|status ; Print help or status information<\\r><\\n>\r\n dump ; Dump data information<\\r><\\n>\r\n erase ; Erase data information<\\r><\\n>\r\nMcuMinINI ; Group of McuMinINI commands<\\r><\\n>\r\n help|status ; Print help or status information<\\r><\\n>\r\n read ; Read a key from a section in a file<\\r><\\n>\r\n write ; Write a key with value to a section in a file<\\r><\\n>\r\n delkey ; Delete a key in a section of file<\\r><\\n>\r\n delsec ; Delete a section in a file<\\r><\\n>\r\nnvmc ; Group of NVMC commands<\\r><\\n>\r\n help|status ; Print help or status information<\\r><\\n>\r\n flags ; Set flags<\\r><\\n>\r\nrs ; Group of RS-485 commands<\\r><\\n>\r\n help|status ; Print help or status information<\\r><\\n>\r\n addr ; Set RS-485 address<\\r><\\n>\r\n send ; Send a text to the RS-485 bus<\\r><\\n>\r\n sendcmd ; Send a shell command to the RS-485 address and check response<\\r><\\n>\r\n log on|off ; Log RS-485 bus activity to McuLog<\\r><\\n>\r\nMcuUart485 ; Group of RS-485 commands<\\r><\\n>\r\n help|status ; Print help or status information<\\r><\\n>\r\n clear ; Clear UART ISR flags<\\r><\\n>\r\n<\\r><\\n>\r\nCMD>"; string exampleData = "This is some example Text\nSecond line\nNow a very long line: Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua."; int counter = 0; - List listOfChars = new(); + int lineNumber = 1; + //List listOfChars = new(); foreach (var character in exampleData) { if(++counter > 100 || character == '\n') { - this.ReceivedData.Add(new DataLine(listOfChars)); - listOfChars = new List(); + //this.ReceivedData.Add(); + //listOfChars = new List(); counter = 0; + lineNumber += 1; } var extdChar = new ExtendedChar(character); - listOfChars.Add(extdChar); - this.ReceivedCharacters.Add(extdChar); + //listOfChars.Add(extdChar); + this.ReceivedData.Add(new DataViewModel(extdChar, lineNumber)); } } } @@ -87,7 +89,7 @@ public partial class CommunicationDataViewModel : ObservableObject [RelayCommand] private void ClearReceivedCharacters() { - this.ReceivedData = new ObservableCollection(); + this.ReceivedData = new ObservableCollection(); } [RelayCommand] diff --git a/MultiTerm.Core/ViewModel/DataViewModel.cs b/MultiTerm.Core/ViewModel/DataViewModel.cs new file mode 100644 index 0000000..c3e5c8c --- /dev/null +++ b/MultiTerm.Core/ViewModel/DataViewModel.cs @@ -0,0 +1,47 @@ +using CommunityToolkit.Mvvm.ComponentModel; +using MultiTerm.Protocols.Model; + +namespace MultiTerm.Core.ViewModel; + +public partial class DataViewModel : ObservableObject +{ + /// + /// Identifier for the frontend to group lines. + /// + [ObservableProperty] + private int lineIdentifier; + + /// + /// Object of data model. + /// + [ObservableProperty] + private ExtendedChar character; + + /// + /// Property that hosts a displayable string of the character (UTF-16 encoded). + /// + [ObservableProperty] + private string displayStringUtf16 = String.Empty; + + /// + /// Property that hosts a string of the character (hexadecimal format). + /// + [ObservableProperty] + private string displayStringHex = String.Empty; + + /// + /// Property that hosts a string of the character (binary format). + /// + [ObservableProperty] + private string displayStringBin = String.Empty; + + + public DataViewModel(ExtendedChar character, int lineIdentifier) + { + this.character = character; + this.lineIdentifier = lineIdentifier; + this.DisplayStringUtf16 = character.ToUtf16String(); + this.DisplayStringHex = character.ToHexString(); + this.DisplayStringBin = character.ToBinaryString(); + } +} diff --git a/MultiTerm.Protocols/Model/DataLine.cs b/MultiTerm.Protocols/Model/DataLine.cs deleted file mode 100644 index c9213a5..0000000 --- a/MultiTerm.Protocols/Model/DataLine.cs +++ /dev/null @@ -1,28 +0,0 @@ -using CommunityToolkit.Mvvm.ComponentModel; -using System.Collections.ObjectModel; - -namespace MultiTerm.Protocols.Model; - -/// -/// One line of data(characters). -/// -public partial class DataLine : ObservableObject -{ - /// - /// Represents the collection of characters from a communication protocol. - /// - [ObservableProperty] - private ObservableCollection characters = new(); - - /// - /// Constructor of . - /// - /// characters collection - public DataLine(IEnumerable characters) - { - foreach (var character in characters) - { - this.Characters.Add(character); - } - } -} diff --git a/MultiTerm.Protocols/Model/ExtendedChar.cs b/MultiTerm.Protocols/Model/ExtendedChar.cs index 0b158f7..031aea3 100644 --- a/MultiTerm.Protocols/Model/ExtendedChar.cs +++ b/MultiTerm.Protocols/Model/ExtendedChar.cs @@ -8,31 +8,13 @@ namespace MultiTerm.Protocols.Model; /// A time can be stored in combination with this Character using the property. E.g. to represent arrived or sent time. /// Several methods to display the Character in other formats than Unicode are provided. /// -public partial class ExtendedChar : ObservableObject +public partial class ExtendedChar { /// /// Data in the form of a character. UTF-16 code unit. /// public char Character { get; set; } - /// - /// Property that hosts a displayable string of the character (UTF-16 encoded). - /// - [ObservableProperty] - private string displayStringUtf16 = String.Empty; - - /// - /// Property that hosts a string of the character (hexadecimal format). - /// - [ObservableProperty] - private string displayStringHex = String.Empty; - - /// - /// Property that hosts a string of the character (binary format). - /// - [ObservableProperty] - private string displayStringBin = String.Empty; - /// /// Time that is associated with the . /// E.g. to represent arrived or sent time. @@ -56,9 +38,6 @@ public partial class ExtendedChar : ObservableObject { this.Character = character; this.Time = time; - this.DisplayStringUtf16 = this.ToUtf16String(); - this.DisplayStringHex = this.ToHexString(); - this.DisplayStringBin = this.ToBinaryString(); } public override string ToString() diff --git a/MultiTerm.Wpf.CustomControl/MultiFormatDataView/MultiFormatDataView.cs b/MultiTerm.Wpf.CustomControl/MultiFormatDataView/MultiFormatDataView.cs index 9af48cd..922bb69 100644 --- a/MultiTerm.Wpf.CustomControl/MultiFormatDataView/MultiFormatDataView.cs +++ b/MultiTerm.Wpf.CustomControl/MultiFormatDataView/MultiFormatDataView.cs @@ -1,10 +1,10 @@ -using MultiTerm.Protocols.Model; +using MultiTerm.Core.ViewModel; using System; using System.Collections; using System.ComponentModel; -using System.Runtime.CompilerServices; using System.Windows; using System.Windows.Controls; +using System.Windows.Data; namespace MultiTerm.Wpf.CustomControl; @@ -39,6 +39,9 @@ namespace MultiTerm.Wpf.CustomControl; /// public class MultiFormatDataView : Control { + private const string itemsControlTemplateName = "itemsControl"; + private ItemsControl? itemsControl; + #region Dependency Properties public static readonly DependencyProperty DataSourceProperty = DependencyProperty.Register("DataSource", @@ -65,7 +68,19 @@ public class MultiFormatDataView : Control public override void OnApplyTemplate() { base.OnApplyTemplate(); + + // get itemsControl from template + if (GetTemplateChild(itemsControlTemplateName) is ItemsControl itemsControl) + { + this.itemsControl = itemsControl; + } + else + { + throw new Exception($"Implementation fault, {itemsControlTemplateName} not found in template."); + } + } + private static void OnDataSourcePropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) { // extract instance and guard null @@ -76,8 +91,13 @@ public class MultiFormatDataView : Control // check if enumerable items are all of correct type foreach (var item in enumerable) { - if (item is not DataLine) - { throw new ArgumentException($"{nameof(DataSourceProperty)} must be of type {nameof(DataLine)}"); } + if (item is not DataViewModel) + { throw new ArgumentException($"{nameof(DataSourceProperty)} must be of type {nameof(DataViewModel)}"); } } + + // add group property + CollectionView view = (CollectionView)CollectionViewSource.GetDefaultView(e.NewValue); + PropertyGroupDescription groupDescription = new(nameof(DataViewModel.LineIdentifier)); + view.GroupDescriptions.Add(groupDescription); } } diff --git a/MultiTerm.Wpf.CustomControl/MultiFormatDataView/MultiFormatDataView.xaml b/MultiTerm.Wpf.CustomControl/MultiFormatDataView/MultiFormatDataView.xaml index 4f01afb..d597051 100644 --- a/MultiTerm.Wpf.CustomControl/MultiFormatDataView/MultiFormatDataView.xaml +++ b/MultiTerm.Wpf.CustomControl/MultiFormatDataView/MultiFormatDataView.xaml @@ -89,42 +89,30 @@ - - - - - - - - + HorizontalAlignment="Left" + VirtualizingPanel.IsVirtualizingWhenGrouping="True" + ItemTemplate="{StaticResource dataContainerTemplate}"> - - - - - - - - - - - - - + + + + + - - + - + - + diff --git a/MultiTerm.Wpf/View/SendReceiveView.xaml b/MultiTerm.Wpf/View/SendReceiveView.xaml index 7e109a5..4407871 100644 --- a/MultiTerm.Wpf/View/SendReceiveView.xaml +++ b/MultiTerm.Wpf/View/SendReceiveView.xaml @@ -18,7 +18,7 @@ - + @@ -32,7 +32,7 @@ - +