worked on MultiFormatTextBox

master
Jonas Arnold 3 years ago
parent 6651dfb381
commit 8bd6a14297
  1. 5
      MultiTerm.Protocols/Serial/SerialProtocolSettingsViewModel.cs
  2. 90
      MultiTerm.Wpf.CustomControl/MultiFormatTextBox/MultiFormatTextBox.cs
  3. 35
      MultiTerm.Wpf.CustomControl/MultiFormatTextBox/MultiFormatTextBox.xaml
  4. 10
      MultiTerm.Wpf/ValueConverters/IntToStringConverter.cs

@ -67,6 +67,11 @@ public partial class SerialProtocolSettingsViewModel : ProtocolSettingsViewModel
this.messenger.Send<IUserInterfaceMessage>(new ProtocolSettingsInvalidMessage(nameof(this.DataBits), "Must be 5...8 or 16"));
return false;
}
if(this.BaudRate < 0)
{
this.messenger.Send<IUserInterfaceMessage>(new ProtocolSettingsInvalidMessage(nameof(this.BaudRate), "Must be larger than 0"));
return false;
}
return true;
}

@ -1,5 +1,11 @@
using System.Windows;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.CompilerServices;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Input;
using System.Windows.Media;
namespace MultiTerm.Wpf.CustomControl;
@ -32,10 +38,90 @@ namespace MultiTerm.Wpf.CustomControl;
/// <MyNamespace:MultiFormatTextBox/>
///
/// </summary>
public class MultiFormatTextBox : TextBox
internal class Format
{
public string Name { get; set; }
public Brush BackgroundBrush { get; set; }
public Predicate<Key> IsKeyValid { get; set; }
public Format(string name, Brush backgroundBrush, Predicate<Key> keyValidator)
{
this.Name = name;
this.BackgroundBrush = backgroundBrush;
this.IsKeyValid = keyValidator;
}
public static List<string> GetListOfNames(IEnumerable<Format> formats)
{
return formats.Select(item => item.Name).ToList();
}
}
public class MultiFormatTextBox : Control
{
private static readonly List<Format> formats = new()
{
// character input, accepts all keys
new Format("CHAR", Brushes.White, delegate(Key k) { return true; }),
// 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); }),
// binary input, ignores all keys except 0 and 1
new Format("BIN", Brushes.AliceBlue, delegate(Key k) { return (k == Key.D0 || k == Key.D1); })
};
private ComboBox comboBox;
private RichTextBox richTextBox;
private Format currentlySelectedFormat = formats.First();
static MultiFormatTextBox()
{
DefaultStyleKeyProperty.OverrideMetadata(typeof(MultiFormatTextBox), new FrameworkPropertyMetadata(typeof(MultiFormatTextBox)));
}
public override void OnApplyTemplate()
{
base.OnApplyTemplate();
// get comboBox from template
var comboBox = GetTemplateChild("comboBox") as ComboBox;
if (comboBox != null)
{
this.comboBox = comboBox;
this.comboBox.ItemsSource = Format.GetListOfNames(formats);
this.comboBox.SelectedItem = currentlySelectedFormat.Name;
this.comboBox.SelectionChanged += ComboBox_SelectionChanged;
}
// get richTextBox from template
var richTextBox = GetTemplateChild("richTextBox") as RichTextBox;
if (richTextBox != null)
{
this.richTextBox = richTextBox;
this.richTextBox.KeyDown += RichTextBox_KeyDown;
}
}
private void ComboBox_SelectionChanged(object sender, SelectionChangedEventArgs e)
{
// match all formats with the name selected in the combobox
var matchingFormats = formats.Where(format => format.Name == (string)this.comboBox!.SelectedItem);
// check if exactly one format was matched
if(matchingFormats.Count() != 1)
{
throw new Exception($"{nameof(ComboBox_SelectionChanged)} could not match a correct amount of formats");
}
// set currently selected format
this.currentlySelectedFormat = matchingFormats.First();
}
private void RichTextBox_KeyDown(object sender, KeyEventArgs e)
{
// guard combobox null
if (comboBox == null) throw new Exception($"{nameof(comboBox)} cannot be null");
// if key is invalid for this format => ignore it (handled = true)
if(this.currentlySelectedFormat.IsKeyValid(e.Key) == false)
{
e.Handled = true;
}
}
}

@ -2,11 +2,11 @@
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="clr-namespace:MultiTerm.Wpf.CustomControl">
<SolidColorBrush x:Key="TextBox.Static.Border" Color="#FFABAdB3"/>
<!--<SolidColorBrush x:Key="TextBox.Static.Border" Color="#FFABAdB3"/>
<SolidColorBrush x:Key="TextBox.MouseOver.Border" Color="#FF7EB4EA"/>
<SolidColorBrush x:Key="TextBox.Focus.Border" Color="#FF569DE5"/>
<SolidColorBrush x:Key="TextBox.Focus.Border" Color="#FF569DE5"/>-->
<Style TargetType="{x:Type local:MultiFormatTextBox}">
<Setter Property="Background" Value="{DynamicResource {x:Static SystemColors.WindowBrushKey}}"/>
<!--<Setter Property="Background" Value="{DynamicResource {x:Static SystemColors.WindowBrushKey}}"/>
<Setter Property="BorderBrush" Value="{StaticResource TextBox.Static.Border}"/>
<Setter Property="Foreground" Value="{DynamicResource {x:Static SystemColors.ControlTextBrushKey}}"/>
<Setter Property="BorderThickness" Value="1"/>
@ -15,21 +15,15 @@
<Setter Property="FocusVisualStyle" Value="{x:Null}"/>
<Setter Property="AllowDrop" Value="true"/>
<Setter Property="ScrollViewer.PanningMode" Value="VerticalFirst"/>
<Setter Property="Stylus.IsFlicksEnabled" Value="False"/>
<Setter Property="Stylus.IsFlicksEnabled" Value="False"/>-->
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type local:MultiFormatTextBox}">
<DockPanel LastChildFill="True">
<ComboBox DockPanel.Dock="Left" x:Name="comboBox" Width="60">
<ComboBoxItem>CHAR</ComboBoxItem>
<ComboBoxItem>HEX</ComboBoxItem>
<ComboBoxItem>BIN</ComboBoxItem>
</ComboBox>
<Border DockPanel.Dock="Right" x:Name="border" Background="{TemplateBinding Background}" BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="{TemplateBinding BorderThickness}" Width="{TemplateBinding Width}" SnapsToDevicePixels="True">
<ScrollViewer x:Name="PART_ContentHost" Focusable="false" HorizontalScrollBarVisibility="Hidden" VerticalScrollBarVisibility="Hidden"/>
</Border>
<ComboBox DockPanel.Dock="Left" x:Name="comboBox" Width="60"></ComboBox>
<RichTextBox DockPanel.Dock="Right" x:Name="richTextBox"></RichTextBox>
</DockPanel>
<ControlTemplate.Triggers>
<!--<ControlTemplate.Triggers>
<Trigger Property="IsEnabled" Value="false">
<Setter Property="Opacity" TargetName="border" Value="0.56"/>
</Trigger>
@ -39,18 +33,13 @@
<Trigger Property="IsKeyboardFocused" Value="true">
<Setter Property="BorderBrush" TargetName="border" Value="{StaticResource TextBox.Focus.Border}"/>
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate.Triggers>-->
</ControlTemplate>
</Setter.Value>
</Setter>
<Style.Triggers>
<MultiTrigger>
<MultiTrigger.Conditions>
<Condition Property="IsInactiveSelectionHighlightEnabled" Value="true"/>
<Condition Property="IsSelectionActive" Value="false"/>
</MultiTrigger.Conditions>
<Setter Property="SelectionBrush" Value="{DynamicResource {x:Static SystemColors.InactiveSelectionHighlightBrushKey}}"/>
</MultiTrigger>
</Style.Triggers>
<!--<Setter Property="MinWidth" Value="10"/>
<Style.BasedOn>
<StaticResource ResourceKey="{x:Type RichTextBox}"/>
</Style.BasedOn>-->
</Style>
</ResourceDictionary>

@ -17,6 +17,14 @@ public class IntToStringConverter : IValueConverter
{
// guard type
if (value is not string stringVal) { throw new ArgumentException("Can only convert from string value"); }
return int.Parse(stringVal);
// try parsing to int
int parsedVal;
if(int.TryParse(stringVal, out parsedVal) == false)
{
// error
parsedVal = -1;
}
return parsedVal;
}
}

Loading…
Cancel
Save