Created
May 17, 2016 14:02
-
-
Save mvacha/79255a156347b1e4f3cc520dc93fd84a to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
using System; | |
using System.Collections.Generic; | |
using System.Linq; | |
using System.Text; | |
using System.Threading.Tasks; | |
using System.Windows; | |
using System.Windows.Controls; | |
using System.Windows.Input; | |
namespace WpfTest | |
{ | |
public enum MaskType | |
{ | |
None = 0, | |
Isic = 1, | |
} | |
public partial class TextBoxExt | |
{ | |
#region Dependency Property | |
public static readonly DependencyProperty MaskProperty = DependencyProperty.RegisterAttached("Mask", | |
typeof(MaskType), typeof(TextBoxExt), new FrameworkPropertyMetadata(MaskChangedCallback)); | |
public static MaskType GetMask(DependencyObject obj) | |
{ | |
return (MaskType)obj.GetValue(MaskProperty); | |
} | |
public static void SetMask(DependencyObject obj, MaskType value) | |
{ | |
obj.SetValue(MaskProperty, value); | |
} | |
private static void MaskChangedCallback(DependencyObject d, DependencyPropertyChangedEventArgs e) | |
{ | |
var oldVal = e.OldValue as TextBox; | |
if (oldVal != null) | |
{ | |
oldVal.PreviewTextInput -= TextBox_PreviewTextInput; | |
oldVal.PreviewKeyDown -= TextBox_PreviewKeyDown; | |
DataObject.RemovePastingHandler(oldVal, (DataObjectPastingEventHandler)TextBoxPastingEventHandler); | |
} | |
var textBox = d as TextBox; | |
if (textBox == null) | |
return; | |
if ((MaskType)e.NewValue != MaskType.None) | |
{ | |
textBox.PreviewTextInput += TextBox_PreviewTextInput; | |
textBox.PreviewKeyDown += TextBox_PreviewKeyDown; | |
DataObject.AddPastingHandler(textBox, (DataObjectPastingEventHandler)TextBoxPastingEventHandler); | |
} | |
} | |
#endregion | |
private static void TextBox_PreviewKeyDown(object sender, KeyEventArgs e) | |
{ | |
var textBox = sender as TextBox; | |
if (textBox == null) return; | |
var caret = textBox.CaretIndex; | |
var oldText = textBox.Text; | |
if (e.Key == Key.Back) | |
{ | |
if (oldText.Length == 0 || caret == 0) | |
{ | |
e.Handled = true; | |
textBox.Text = oldText; | |
return; | |
} | |
if (textBox.SelectionLength > 0) | |
{ | |
oldText = oldText.Remove(textBox.SelectionStart, textBox.SelectionLength); | |
caret = textBox.SelectionStart; | |
textBox.Text = FormatValue(GetMask(textBox), oldText); | |
textBox.CaretIndex = FixCaretIndex(GetMask(textBox), caret, oldText, true, false); | |
e.Handled = true; | |
} | |
var newText = oldText.Remove(caret-1, 1); | |
caret -= 1; | |
if (newText.Any() && caret > 0 && newText[caret-1] == ' ') | |
{ | |
newText = newText.Remove(caret - 1, 1); | |
caret -= 1; | |
} | |
textBox.Text = FormatValue(GetMask(textBox), newText); | |
textBox.CaretIndex = FixCaretIndex(GetMask(textBox), caret, newText, true, false); | |
e.Handled = true; | |
} | |
else if (e.Key == Key.Delete) | |
{ | |
if (oldText.Length == 0 || oldText.Length == caret) | |
{ | |
e.Handled = true; | |
textBox.Text = oldText; | |
return; | |
} | |
if (textBox.SelectionLength > 0) | |
{ | |
oldText = oldText.Remove(textBox.SelectionStart, textBox.SelectionLength); | |
caret = textBox.SelectionStart; | |
textBox.Text = FormatValue(GetMask(textBox), oldText); | |
textBox.CaretIndex = FixCaretIndex(GetMask(textBox), caret, oldText, false, true); | |
e.Handled = true; | |
} | |
var newText = oldText.Remove(caret, 1); | |
if (caret < newText.Length && newText[caret] == ' ') | |
{ | |
newText = newText.Remove(caret, 1); | |
} | |
textBox.Text = FormatValue(GetMask(textBox), newText); | |
textBox.CaretIndex = FixCaretIndex(GetMask(textBox), caret, newText, false, true); | |
e.Handled = true; | |
} | |
else if (e.Key == Key.Right) | |
{ | |
caret += 1; | |
if (caret < textBox.Text.Length && textBox.Text[caret] == ' ') | |
{ | |
caret += 1; | |
} | |
textBox.CaretIndex = caret; | |
e.Handled = true; | |
} | |
else if (e.Key == Key.Left) | |
{ | |
caret = Math.Max( caret - 1, 0); | |
if (caret > 0 && textBox.Text[caret-1] == ' ') | |
{ | |
caret -= 1; | |
} | |
textBox.CaretIndex = caret; | |
e.Handled = true; | |
} | |
else if (e.Key == Key.Space) | |
{ | |
e.Handled = true; | |
} | |
} | |
private static void TextBoxPastingEventHandler(object sender, DataObjectPastingEventArgs e) | |
{ | |
TextBox tb = (sender as TextBox); | |
var text = tb.Text; | |
var caret = tb.CaretIndex; | |
string clipboard = e.DataObject.GetData(typeof(string)) as string; | |
if (tb.SelectionLength != 0) | |
{ | |
text = text.Remove(tb.SelectionStart, tb.SelectionLength); | |
caret = tb.SelectionStart; | |
} | |
text = text.Insert(caret, clipboard); | |
caret += clipboard.Length; | |
tb.Text = FormatValue(GetMask(tb), text); | |
tb.CaretIndex = tb.Text.Length; | |
e.CancelCommand(); | |
e.Handled = true; | |
} | |
private static void TextBox_PreviewTextInput(object sender, TextCompositionEventArgs e) | |
{ | |
var textbox = sender as TextBox; | |
if (textbox == null) return; | |
e.Handled = false; | |
var caretIndex = textbox.CaretIndex; | |
var text = textbox.Text; | |
if (textbox.SelectionLength != 0) | |
{ | |
text = text.Remove(textbox.SelectionStart, textbox.SelectionLength); | |
} | |
var newText = FormatValue(GetMask(textbox), text.Insert(caretIndex, e.Text)); | |
textbox.Text = newText; | |
caretIndex += 1; | |
textbox.CaretIndex = FixCaretIndex(GetMask(textbox), caretIndex, newText, true, false); | |
e.Handled = true; | |
} | |
private static int FixCaretIndex(MaskType mask, int caretIndex, string text, bool moveForward = true, bool moveBackward = true) | |
{ | |
if (moveBackward && caretIndex < text.Length && text[caretIndex] == ' ') | |
{ | |
caretIndex -= 1; | |
} | |
else if (moveForward && caretIndex < text.Length && caretIndex > 0 && text[caretIndex - 1] == ' ') | |
{ | |
caretIndex += 1; | |
} | |
if (caretIndex >= text.Length) | |
{ | |
caretIndex = text.Length; | |
} | |
return caretIndex; | |
} | |
private static string FormatValue(MaskType mask, string value) | |
{ | |
if (mask != MaskType.Isic) return String.Empty; | |
var sbuilder = new StringBuilder(); | |
var index = 0; | |
value = value.RemoveWhitespace().ToUpper(); | |
if (value.Length > 11) | |
value = value.Substring(0, 11); | |
foreach (var ch in value) | |
{ | |
if (ch != ' ' && (index == 1 || index == 4 || index == 7 || index == 10)) | |
{ | |
sbuilder.Append(' '); | |
} | |
sbuilder.Append(ch); | |
index++; | |
} | |
return sbuilder.ToString(); | |
} | |
} | |
public static class Extensions | |
{ | |
public static string RemoveWhitespace(this string input) | |
{ | |
return new string(input.ToCharArray() | |
.Where(c => !Char.IsWhiteSpace(c)) | |
.ToArray()); | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment