Winforms MaskedTextBox - reformatting inserted text to match mask

I have a MaskedTextBox control, which in our case collects social security (tax) numbers (without ValidatingType, although from a string representation, including mask literals). Social Security Number - 3 groups of 3 digits separated by a dash. Sometimes spaces can be entered or entered instead of dashes.

Text field configuration:

  • Mask: 999-999-999
  • ValidationType: null / not required
  • SkipLiterals: true
  • CutCopyMaskFormat: IncludeLiterals (applicable only when cutting / copying from a text field)
  • TextMaskFormat: IncludeLiterals

- Let me know if there are other properties that you consider important!

Problem

When pasting the next tax number "450 622 097" due to spaces, it does not match the mask. That way I get "450-62-2 9" in the text box. Insert "450-622-097" is successfully inserted into the box.

I want to be able to capture an insert event, to possibly fix it, to replace dashes with spaces.

Alternatively, is it possible to force the mask to accept spaces OR spaces (but always display dashes)?

Non-solutions

MaskInputRejected event - I can’t understand what was originally entered (that is, what is rejected) in order to compare it with what is at the top of the clipboard. He just returns how he was rejected.

Checking event - already occurs after applying the mask. That is, the value "450-62-2 9" is in the text box.

Use a special ValidatingType with a static Parse function - Again, it happens after applying the mask.

Key-down event detection. Then, if the series of keys is Ctrl-V, manually process and transfer the cleared version of the clipboard text. Could work, but then what about pasting right-click through the context menu?

Any other ideas?

+4
source share
2 answers

Although this solution is for the hammer, there are limitations to the mask string, and I do not see another way. You need to capture the insert event and process the text before it gets into the text field. Below is a simplified example.

class MyMaskedTextbox : MaskedTextBox { const int WM_PASTE = 0x0302; protected override void WndProc(ref Message m) { switch (m.Msg) { case WM_PASTE: if (Clipboard.ContainsText()) { string text = Clipboard.GetText(); text = text.Replace(' ', '-'); //put your processing here Clipboard.SetText(text); } break; } base.WndProc(ref m); } } 
+3
source

According to @anchandra's answer and the following comments, a class is presented here that allows you to process text based on control.

 public class MyMaskedTextBox : MaskedTextBox { private const int WM_PASTE = 0x0302; protected override void WndProc(ref Message m) { switch (m.Msg) { case WM_PASTE: if (Clipboard.ContainsText()) { string text = Clipboard.GetText(); var args = OnPasting(text); if (args.Cancel) { // Swallow it up! return; } // If value changed, then change what we'll paste from the top of the clipboard if (!args.Value.Equals(text, StringComparison.CurrentCulture)) { Clipboard.SetText(args.Value); } } break; } base.WndProc(ref m); } public event EventHandler<PastingEventArgs> Pasting; protected virtual PastingEventArgs OnPasting(string value) { var handler = Pasting; var args = new PastingEventArgs(value); if (handler != null) { handler(this, args); } return args; } } public class PastingEventArgs : CancelEventArgs { public string Value { get; set; } public PastingEventArgs(string value) { Value = value; } } 

And a simple use of the insert event to highlight spaces according to:

 private void sinTextBox_Pasting(object sender, PastingEventArgs e) { e.Value = e.Value.Replace(" ", String.Empty); } 
+1
source

Source: https://habr.com/ru/post/1310416/


All Articles