patterncsharpMinor
Filtered WPF textbox
Viewed 0 times
wpftextboxfiltered
Problem
I am trying to make a textbox which filters user input to match specified type, so I can discard some of my validation logic.
For example, if I specify
This is what I've ended up with:
```
public abstract class CustomTextBox : TextBox
{
public static readonly DependencyProperty ValueProperty = DependencyProperty.Register("Value", typeof(T), typeof(CustomTextBox), new FrameworkPropertyMetadata(default(T), FrameworkPropertyMetadataOptions.BindsTwoWayByDefault | FrameworkPropertyMetadataOptions.Inherits, OnValueChanged));
public T Value
{
get { return (T)GetValue(ValueProperty); }
set { SetValue(ValueProperty, value); }
}
protected override void OnPreviewTextInput(System.Windows.Input.TextCompositionEventArgs e)
{
if (_regex != null && !_regex.IsMatch(e.Text))
{
e.Handled = true;
}
else
{
base.OnPreviewTextInput(e);
}
}
protected override void OnTextChanged(TextChangedEventArgs e)
{
if (String.IsNullOrEmpty(Text))
{
return;
}
T val;
if (!TryParse(out val))
{
var index = CaretIndex;
Text = _validText;
CaretIndex = index > 0 ? index - 1 : 0;
e.Handled = true;
}
else
{
Value = val;
_validText = Text;
}
}
protected CustomTextBox(string regexPattern = null)
{
if (!String.IsNullOrEmpty(regexPattern))
{
_regex = new Regex(regexPattern);
}
_validText = ToString(Value);
Loaded += OnTextboxLoaded;
}
protected override void OnLostFocus(RoutedEventArgs e)
{
ValidateText();
base.OnLostFocus(e);
}
protected virtual string ToString(T value)
{
return value.ToString();
For example, if I specify
ushort I want my textbox to only accept text changes which result in a valid ushort value and nothing else.This is what I've ended up with:
```
public abstract class CustomTextBox : TextBox
{
public static readonly DependencyProperty ValueProperty = DependencyProperty.Register("Value", typeof(T), typeof(CustomTextBox), new FrameworkPropertyMetadata(default(T), FrameworkPropertyMetadataOptions.BindsTwoWayByDefault | FrameworkPropertyMetadataOptions.Inherits, OnValueChanged));
public T Value
{
get { return (T)GetValue(ValueProperty); }
set { SetValue(ValueProperty, value); }
}
protected override void OnPreviewTextInput(System.Windows.Input.TextCompositionEventArgs e)
{
if (_regex != null && !_regex.IsMatch(e.Text))
{
e.Handled = true;
}
else
{
base.OnPreviewTextInput(e);
}
}
protected override void OnTextChanged(TextChangedEventArgs e)
{
if (String.IsNullOrEmpty(Text))
{
return;
}
T val;
if (!TryParse(out val))
{
var index = CaretIndex;
Text = _validText;
CaretIndex = index > 0 ? index - 1 : 0;
e.Handled = true;
}
else
{
Value = val;
_validText = Text;
}
}
protected CustomTextBox(string regexPattern = null)
{
if (!String.IsNullOrEmpty(regexPattern))
{
_regex = new Regex(regexPattern);
}
_validText = ToString(Value);
Loaded += OnTextboxLoaded;
}
protected override void OnLostFocus(RoutedEventArgs e)
{
ValidateText();
base.OnLostFocus(e);
}
protected virtual string ToString(T value)
{
return value.ToString();
Solution
I think you can avoid inheritance here ("Favor Composition Over Inheritance") and use Attached Behavior instead.
Also, did you take a look at MaskedTextBox from Extended WPF Toolkit (http://wpftoolkit.codeplex.com/wikipage?title=MaskedTextBox)?
Also, did you take a look at MaskedTextBox from Extended WPF Toolkit (http://wpftoolkit.codeplex.com/wikipage?title=MaskedTextBox)?
Context
StackExchange Code Review Q#27620, answer score: 3
Revisions (0)
No revisions yet.