You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
127 lines
4.5 KiB
127 lines
4.5 KiB
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;
|
|
|
|
/// <summary>
|
|
/// Follow steps 1a or 1b and then 2 to use this custom control in a XAML file.
|
|
///
|
|
/// Step 1a) Using this custom control in a XAML file that exists in the current project.
|
|
/// Add this XmlNamespace attribute to the root element of the markup file where it is
|
|
/// to be used:
|
|
///
|
|
/// xmlns:MyNamespace="clr-namespace:MultiTerm.Wpf.CustomControl"
|
|
///
|
|
///
|
|
/// Step 1b) Using this custom control in a XAML file that exists in a different project.
|
|
/// Add this XmlNamespace attribute to the root element of the markup file where it is
|
|
/// to be used:
|
|
///
|
|
/// xmlns:MyNamespace="clr-namespace:MultiTerm.Wpf.CustomControl.MultiFormatTextBox;assembly=MultiTerm.Wpf.CustomControl.MultiFormatTextBox"
|
|
///
|
|
/// You will also need to add a project reference from the project where the XAML file lives
|
|
/// to this project and Rebuild to avoid compilation errors:
|
|
///
|
|
/// Right click on the target project in the Solution Explorer and
|
|
/// "Add Reference"->"Projects"->[Browse to and select this project]
|
|
///
|
|
///
|
|
/// Step 2)
|
|
/// Go ahead and use your control in the XAML file.
|
|
///
|
|
/// <MyNamespace:MultiFormatTextBox/>
|
|
///
|
|
/// </summary>
|
|
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;
|
|
}
|
|
}
|
|
}
|
|
|