From 06f7503586c4013288d3594e8c2ce830548745ff Mon Sep 17 00:00:00 2001 From: Jonas Arnold Date: Fri, 14 Apr 2023 15:47:45 +0200 Subject: [PATCH] implemented change of color in MultiFormatTextBox --- .../MultiFormatTextBox/MultiFormatTextBox.cs | 87 +++++++++++++++++-- 1 file changed, 81 insertions(+), 6 deletions(-) diff --git a/MultiTerm.Wpf.CustomControl/MultiFormatTextBox/MultiFormatTextBox.cs b/MultiTerm.Wpf.CustomControl/MultiFormatTextBox/MultiFormatTextBox.cs index cc274f8..c81bde5 100644 --- a/MultiTerm.Wpf.CustomControl/MultiFormatTextBox/MultiFormatTextBox.cs +++ b/MultiTerm.Wpf.CustomControl/MultiFormatTextBox/MultiFormatTextBox.cs @@ -1,9 +1,11 @@ using System; using System.Collections.Generic; +using System.Drawing; using System.Linq; using System.Runtime.CompilerServices; using System.Windows; using System.Windows.Controls; +using System.Windows.Documents; using System.Windows.Input; using System.Windows.Media; @@ -49,6 +51,14 @@ internal class Format this.BackgroundBrush = backgroundBrush; this.IsKeyValid = keyValidator; } + public Format(string name, string backgroundBrushColorHexCode, Predicate keyValidator) + { + this.Name = name; + var brushObj = new BrushConverter().ConvertFrom(backgroundBrushColorHexCode); + if(brushObj == null) throw new ArgumentException(nameof(backgroundBrushColorHexCode)); + this.BackgroundBrush = (SolidColorBrush)brushObj; + this.IsKeyValid = keyValidator; + } public static List GetListOfNames(IEnumerable formats) { return formats.Select(item => item.Name).ToList(); @@ -57,19 +67,24 @@ internal class Format public class MultiFormatTextBox : Control { + private static readonly Brush defaultBackgroundBrush = Brushes.White; private static readonly List formats = new() { - // character input, accepts all keys - new Format("CHAR", Brushes.White, delegate(Key k) { return true; }), + // character input, accepts all keys except space + new Format("CHAR", Brushes.LightSkyBlue, delegate(Key k) { return (k != Key.Space); }), + //new Format("CHAR", "B4EBEB", delegate(Key k) { return (k != Key.Space); }), // hex input, ignores all keys that are not inbetween 0 and F - new Format("HEX", Brushes.Orange, delegate(Key k) { return (k >= Key.D0 && k <= Key.F); }), + new Format("HEX", Brushes.LightGreen, delegate(Key k) { return (k >= Key.D0 && k <= Key.F); }), + //new Format("HEX", "C8C8FF", delegate(Key k) { return (k >= Key.D0 && k <= Key.F); }), // binary input, ignores all keys except 0 and 1 - new Format("BIN", Brushes.AliceBlue, delegate(Key k) { return (k == Key.D0 || k == Key.D1); }) + new Format("BIN", Brushes.LightPink, delegate(Key k) { return (k == Key.D0 || k == Key.D1); }) + //new Format("BIN", "C8FFC8", delegate(Key k) { return (k == Key.D0 || k == Key.D1); }) }; private ComboBox comboBox; private RichTextBox richTextBox; private Format currentlySelectedFormat = formats.First(); + private int offsetContentStartToFormatStart; static MultiFormatTextBox() { @@ -96,10 +111,13 @@ public class MultiFormatTextBox : Control { this.richTextBox = richTextBox; this.richTextBox.KeyDown += RichTextBox_KeyDown; + this.richTextBox.TextChanged += RichTextBox_TextChanged; + this.offsetContentStartToFormatStart = 0; } } + private void ComboBox_SelectionChanged(object sender, SelectionChangedEventArgs e) { // match all formats with the name selected in the combobox @@ -109,14 +127,47 @@ public class MultiFormatTextBox : Control { throw new Exception($"{nameof(ComboBox_SelectionChanged)} could not match a correct amount of formats"); } - // set currently selected format + // set currently selected format, reset offset counter this.currentlySelectedFormat = matchingFormats.First(); + + // insert space to separate formats + this.InsertSeparation(); + + // set new start position + this.offsetContentStartToFormatStart = this.richTextBox.CaretPosition.GetOffsetToPosition(this.richTextBox.Document.ContentStart); + + // focus textbox + this.richTextBox.Focus(); + } + + private void InsertSeparation() + { + // disable event handler + this.richTextBox.TextChanged -= RichTextBox_TextChanged; + + // store caret position before + this.offsetContentStartToFormatStart = this.richTextBox.CaretPosition.GetOffsetToPosition(this.richTextBox.Document.ContentStart); + + // insert + this.richTextBox.AppendText(" "); + + // change background + RtbChangeTextBackground(this.richTextBox, + start: this.richTextBox.Document.ContentStart.GetPositionAtOffset(-this.offsetContentStartToFormatStart), + end: this.richTextBox.Document.ContentEnd, + color: defaultBackgroundBrush); + + // store new caret position after + this.offsetContentStartToFormatStart = this.richTextBox.CaretPosition.GetOffsetToPosition(this.richTextBox.Document.ContentStart); + + // reenable + this.richTextBox.TextChanged += RichTextBox_TextChanged; } private void RichTextBox_KeyDown(object sender, KeyEventArgs e) { // guard combobox null - if (comboBox == null) throw new Exception($"{nameof(comboBox)} cannot be null"); + if (this.comboBox == null) throw new Exception($"{nameof(this.comboBox)} cannot be null"); // if key is invalid for this format => ignore it (handled = true) if(this.currentlySelectedFormat.IsKeyValid(e.Key) == false) @@ -124,4 +175,28 @@ public class MultiFormatTextBox : Control e.Handled = true; } } + + private void RichTextBox_TextChanged(object sender, TextChangedEventArgs e) + { + if(e.Changes.Count > 1) { return; } + + RtbChangeTextBackground(this.richTextBox, + start: this.richTextBox.Document.ContentStart.GetPositionAtOffset(-this.offsetContentStartToFormatStart), + end: this.richTextBox.Document.ContentEnd, + color: this.currentlySelectedFormat.BackgroundBrush); + } + + private static void RtbChangeTextBackground(RichTextBox rtb, TextPointer start, TextPointer end, Brush color) + { + // Get text selection + TextSelection textRange = rtb.Selection; + textRange.Select(start, end); + + // Apply property to the selection: + textRange.ApplyPropertyValue(TextElement.BackgroundProperty, color); + + // deselect + rtb.Selection.Select(rtb.Document.ContentEnd, rtb.Document.ContentEnd); + } + }