Files
BeWoPlaner/Controls/Controls/MaskedTextBox.cs
2016-06-27 01:45:38 +02:00

206 lines
6.5 KiB
C#

using System.ComponentModel;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Input;
namespace BeWo.Controls
{
public class MaskedTextBox : TextBox
{
/// <summary>
/// Dependency property to store the mask to apply to the textbox
/// </summary>
public static readonly DependencyProperty MaskProperty = DependencyProperty.Register("Mask", typeof(string), typeof(MaskedTextBox), new UIPropertyMetadata(null, MaskChanged));
// callback for when the Mask property is changed
/// <summary>
/// Static Constructor
/// </summary>
static MaskedTextBox()
{
// override the meta data for the Text Proeprty of the textbox
FrameworkPropertyMetadata metaData = new FrameworkPropertyMetadata();
metaData.CoerceValueCallback = ForceText;
TextProperty.OverrideMetadata(typeof(MaskedTextBox), metaData);
}
// force the text of the control to use the mask
///<summary>
/// Default constructor
///</summary>
public MaskedTextBox()
{
// cancel the paste and cut command
this.CommandBindings.Add(new CommandBinding(ApplicationCommands.Paste, null, CancelCommand));
this.CommandBindings.Add(new CommandBinding(ApplicationCommands.Cut, null, CancelCommand));
}
/// <summary>
/// Gets or sets the mask to apply to the textbox
/// </summary>
public string Mask
{
get
{
return (string)this.GetValue(MaskProperty);
}
set
{
this.SetValue(MaskProperty, value);
}
}
/// <summary>
/// Gets the MaskTextProvider for the specified Mask
/// </summary>
public MaskedTextProvider MaskProvider
{
get
{
MaskedTextProvider maskProvider = null;
if (this.Mask != null)
{
maskProvider = new MaskedTextProvider(this.Mask);
maskProvider.Set(this.Text);
}
return maskProvider;
}
}
// cancel the command
/// <summary>
/// override the key down to handle delete of a character
/// </summary>
/// <param name="e">Arguments for the event</param>
protected override void OnPreviewKeyDown(KeyEventArgs e)
{
base.OnPreviewKeyDown(e);
MaskedTextProvider provider = this.MaskProvider;
int position = this.SelectionStart;
if (e.Key == Key.Delete && position < this.Text.Length)
{
// handle the delete key
if (provider.RemoveAt(position))
{
this.RefreshText(provider, position);
}
e.Handled = true;
}
else if (e.Key == Key.Space)
{
if (provider.InsertAt(" ", position))
{
this.RefreshText(provider, position);
}
e.Handled = true;
}
else if (e.Key == Key.Back)
{
// handle the back space
if (position > 0)
{
position--;
if (provider.RemoveAt(position))
{
this.RefreshText(provider, position);
}
}
e.Handled = true;
}
}
/// <summary>
/// override this method to replace the characters enetered with the mask
/// </summary>
/// <param name="e">Arguments for event</param>
protected override void OnPreviewTextInput(TextCompositionEventArgs e)
{
int position = this.SelectionStart;
MaskedTextProvider provider = this.MaskProvider;
if (position < this.Text.Length)
{
position = this.GetNextCharacterPosition(position);
if (Keyboard.IsKeyToggled(Key.Insert))
{
if (provider.Replace(e.Text, position))
{
position++;
}
}
else
{
if (provider.InsertAt(e.Text, position))
{
position++;
}
}
position = this.GetNextCharacterPosition(position);
}
this.RefreshText(provider, position);
e.Handled = true;
base.OnPreviewTextInput(e);
}
private static void CancelCommand(object sender, CanExecuteRoutedEventArgs e)
{
e.CanExecute = false;
e.Handled = true;
}
private static object ForceText(DependencyObject sender, object value)
{
MaskedTextBox textBox = (MaskedTextBox)sender;
if (textBox.Mask != null)
{
MaskedTextProvider provider = new MaskedTextProvider(textBox.Mask);
provider.Set((string)value);
return provider.ToDisplayString();
}
else
{
return value;
}
}
private static void MaskChanged(DependencyObject sender, DependencyPropertyChangedEventArgs e)
{
// make sure to update the text if the mask changes
MaskedTextBox textBox = (MaskedTextBox)sender;
textBox.RefreshText(textBox.MaskProvider, 0);
}
// refreshes the text of the textbox
// gets the next position in the textbox to move
private int GetNextCharacterPosition(int startPosition)
{
int position = this.MaskProvider.FindEditPositionFrom(startPosition, true);
if (position == -1)
{
return startPosition;
}
else
{
return position;
}
}
private void RefreshText(MaskedTextProvider provider, int position)
{
this.Text = provider.ToDisplayString();
this.SelectionStart = position;
}
}
}