4 // Permission is hereby granted, free of charge, to any person obtaining
5 // a copy of this software and associated documentation files (the
6 // "Software"), to deal in the Software without restriction, including
7 // without limitation the rights to use, copy, modify, merge, publish,
8 // distribute, sublicense, and/or sell copies of the Software, and to
9 // permit persons to whom the Software is furnished to do so, subject to
10 // the following conditions:
12 // The above copyright notice and this permission notice shall be
13 // included in all copies or substantial portions of the Software.
15 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
16 // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
17 // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
18 // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
19 // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
20 // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
21 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
23 // Copyright (c) 2007 Novell, Inc.
26 // Rolf Bjarne Kvinge (RKvinge@novell.com)
30 #if NET_2_0// && notyet
33 using System.Collections;
34 using System.ComponentModel;
36 using System.Drawing.Design;
37 using System.Globalization;
38 using System.Runtime.InteropServices;
39 using System.Security.Permissions;
40 using System.Windows.Forms;
42 namespace System.Windows.Forms
44 [ClassInterface (ClassInterfaceType.AutoDispatch)]
46 [DefaultProperty ("Mask")]
47 [DefaultEvent ("MaskInputRejected")]
48 [Designer ("System.Windows.Forms.Design.MaskedTextBoxDesigner, " + Consts.AssemblySystem_Design)]
49 [DefaultBindingProperty ("Text")]
50 public class MaskedTextBox : TextBoxBase
53 private MaskedTextProvider provider;
54 private bool beep_on_error;
55 private IFormatProvider format_provider;
56 private bool hide_prompt_on_leave;
57 private InsertKeyMode insert_key_mode;
58 private bool insert_key_overwriting;
59 private bool reject_input_on_first_failure;
60 private HorizontalAlignment text_align;
61 private MaskFormat cut_copy_mask_format;
62 private bool use_system_password_char;
63 private Type validating_type;
64 private bool is_empty_mask;
65 private bool setting_text;
69 static object AcceptsTabChangedEvent = new object ();
70 static object IsOverwriteModeChangedEvent = new object ();
71 static object MaskChangedEvent = new object ();
72 static object MaskInputRejectedEvent = new object ();
73 static object MultilineChangedEvent = new object ();
74 static object TextAlignChangedEvent = new object ();
75 static object TypeValidationCompletedEvent = new object ();
77 // This event is never raised by MaskedTextBox.
78 [DesignerSerializationVisibility (DesignerSerializationVisibility.Hidden)]
80 [EditorBrowsable (EditorBrowsableState.Never)]
81 public new event EventHandler AcceptsTabChanged {
82 add { Events.AddHandler (AcceptsTabChangedEvent, value);}
83 remove { Events.RemoveHandler (AcceptsTabChangedEvent, value);}
86 public event EventHandler IsOverwriteModeChanged {
87 add { Events.AddHandler (IsOverwriteModeChangedEvent, value); }
88 remove { Events.RemoveHandler (IsOverwriteModeChangedEvent, value); }
91 public event EventHandler MaskChanged {
92 add { Events.AddHandler (MaskChangedEvent, value); }
93 remove { Events.RemoveHandler (MaskChangedEvent, value); }
96 public event MaskInputRejectedEventHandler MaskInputRejected {
97 add { Events.AddHandler (MaskInputRejectedEvent, value); }
98 remove { Events.RemoveHandler (MaskInputRejectedEvent, value); }
101 // This event is never raised by MaskedTextBox.
102 [DesignerSerializationVisibility (DesignerSerializationVisibility.Hidden)]
104 [EditorBrowsable (EditorBrowsableState.Never)]
105 public new event EventHandler MultilineChanged {
106 add { Events.AddHandler (MultilineChangedEvent, value); }
107 remove { Events.RemoveHandler (MultilineChangedEvent, value); }
110 public event EventHandler TextAlignChanged {
111 add { Events.AddHandler (TextAlignChangedEvent, value); }
112 remove { Events.RemoveHandler (TextAlignChangedEvent, value); }
115 public event TypeValidationEventHandler TypeValidationCompleted {
116 add { Events.AddHandler (TypeValidationCompletedEvent, value); }
117 remove { Events.RemoveHandler (TypeValidationCompletedEvent, value); }
121 public MaskedTextBox ()
123 provider = new MaskedTextProvider ("<>", CultureInfo.CurrentCulture);
124 is_empty_mask = true;
128 public MaskedTextBox (MaskedTextProvider maskedTextProvider)
130 if (maskedTextProvider == null) {
131 throw new ArgumentNullException ();
133 provider = maskedTextProvider;
137 public MaskedTextBox (string mask)
140 throw new ArgumentNullException ();
142 provider = new MaskedTextProvider (mask, CultureInfo.CurrentCulture);
147 BackColor = SystemColors.Window;
148 cut_copy_mask_format = MaskFormat.IncludeLiterals;
149 UpdateVisibleText ();
152 #region Public and protected methods
153 [EditorBrowsable (EditorBrowsableState.Never)]
154 public new void ClearUndo ()
156 // Do nothing, not supported by MTB
159 [EditorBrowsable (EditorBrowsableState.Advanced)]
160 [UIPermission (SecurityAction.InheritanceDemand, Window = UIPermissionWindow.AllWindows)]
161 protected override void CreateHandle ()
163 base.CreateHandle ();
166 public override char GetCharFromPosition (Point pt)
168 return base.GetCharFromPosition (pt);
171 public override int GetCharIndexFromPosition (Point pt)
173 return base.GetCharIndexFromPosition (pt);
176 [EditorBrowsable (EditorBrowsableState.Never)]
177 public new int GetFirstCharIndexFromLine (int lineNumber)
182 [EditorBrowsable (EditorBrowsableState.Never)]
183 public new int GetFirstCharIndexOfCurrentLine ()
188 [EditorBrowsable (EditorBrowsableState.Never)]
189 public override int GetLineFromCharIndex (int index)
194 public override Point GetPositionFromCharIndex (int index)
196 return base.GetPositionFromCharIndex (index);
199 protected override bool IsInputKey (Keys keyData)
201 return base.IsInputKey (keyData);
204 protected override void OnBackColorChanged (EventArgs e)
206 base.OnBackColorChanged (e);
209 protected override void OnHandleCreated (EventArgs e)
211 base.OnHandleCreated (e);
214 [EditorBrowsable (EditorBrowsableState.Advanced)]
215 protected virtual void OnIsOverwriteModeChanged (EventArgs e)
217 EventHandler eh = (EventHandler) Events [IsOverwriteModeChangedEvent];
222 protected override void OnKeyDown (KeyEventArgs e)
227 protected override void OnKeyPress (KeyPressEventArgs e)
235 MaskedTextResultHint resultHint;
238 if (IsOverwriteMode) {
239 result = provider.InsertAt (e.KeyChar, SelectionStart, out testPosition, out resultHint);
241 result = provider.Replace (e.KeyChar, SelectionStart, SelectionStart, out testPosition, out resultHint);
245 OnMaskInputRejected (new MaskInputRejectedEventArgs (testPosition, resultHint));
248 UpdateVisibleText ();
254 protected override void OnKeyUp (KeyEventArgs e)
259 [EditorBrowsable (EditorBrowsableState.Advanced)]
260 protected virtual void OnMaskChanged (EventArgs e)
262 EventHandler eh = (EventHandler) Events [MaskChangedEvent];
267 private void OnMaskInputRejected (MaskInputRejectedEventArgs e)
269 MaskInputRejectedEventHandler eh = (MaskInputRejectedEventHandler) Events [MaskInputRejectedEvent];
274 [EditorBrowsable (EditorBrowsableState.Never)]
275 protected override void OnMultilineChanged (EventArgs e)
277 EventHandler eh = (EventHandler)Events [MultilineChangedEvent];
282 protected virtual void OnTextAlignChanged (EventArgs e)
284 EventHandler eh = (EventHandler)Events [TextAlignChangedEvent];
289 protected override void OnTextChanged (EventArgs e)
291 base.OnTextChanged (e);
294 [EditorBrowsable (EditorBrowsableState.Advanced)]
295 protected override void OnValidating (CancelEventArgs e)
297 base.OnValidating (e);
300 //[SecurityPermission (SecurityAction.LinkDemand, Flags = SecurityPermissionFlag.UnmanagedCode)]
301 protected override bool ProcessCmdKey (ref Message msg, Keys keyData)
303 return base.ProcessCmdKey (ref msg, keyData);
306 //[SecurityPermission (SecurityAction.LinkDemand, Flags = SecurityPermissionFlag.UnmanagedCode)]
307 protected internal override bool ProcessKeyMessage (ref Message m)
309 return base.ProcessKeyMessage (ref m);
312 [EditorBrowsable (EditorBrowsableState.Never)]
313 public new void ScrollToCaret ()
315 // MSDN: this method is overridden to perform no actions.
318 public override string ToString ()
320 return base.ToString () + ", Text: " + provider.ToString (false, false);
323 [EditorBrowsable (EditorBrowsableState.Never)]
324 public new void Undo ()
326 // Do nothing, not supported by MTB.
329 public object ValidateText ()
331 throw new NotImplementedException ();
334 //[SecurityPermission (SecurityAction.LinkDemand, Flags = SecurityPermissionFlag.UnmanagedCode)]
335 protected override void WndProc (ref Message m)
340 base.WndProc (ref m);
346 [EditorBrowsable (EditorBrowsableState.Never)]
347 [DesignerSerializationVisibility (DesignerSerializationVisibility.Hidden)]
349 public new bool AcceptsTab {
357 [DefaultValue (true)]
358 public bool AllowPromptAsInput {
360 return provider.AllowPromptAsInput;
363 provider = new MaskedTextProvider (provider.Mask, provider.Culture, value, provider.PromptChar, provider.PasswordChar, provider.AsciiOnly);
364 UpdateVisibleText ();
368 [RefreshProperties (RefreshProperties.Repaint)]
369 [DefaultValue (false)]
370 public bool AsciiOnly {
372 return provider.AsciiOnly;
375 provider = new MaskedTextProvider (provider.Mask, provider.Culture, provider.AllowPromptAsInput, provider.PromptChar, provider.PasswordChar, value);
376 UpdateVisibleText ();
380 [DefaultValue (false)]
381 public bool BeepOnError {
383 return beep_on_error;
386 beep_on_error = value;
391 [DesignerSerializationVisibility (DesignerSerializationVisibility.Hidden)]
392 [EditorBrowsable (EditorBrowsableState.Never)]
393 public new bool CanUndo {
399 protected override CreateParams CreateParams {
400 //[SecurityPermission (SecurityAction.LinkDemand, Flags = SecurityPermissionFlag.UnmanagedCode)]
402 return base.CreateParams;
406 [RefreshProperties (RefreshProperties.Repaint)]
407 public CultureInfo Culture {
409 return provider.Culture;
412 provider = new MaskedTextProvider (provider.Mask, value, provider.AllowPromptAsInput, provider.PromptChar, provider.PasswordChar, provider.AsciiOnly);
413 UpdateVisibleText ();
417 [RefreshProperties (RefreshProperties.Repaint)]
418 [DefaultValue (MaskFormat.IncludeLiterals)]
419 public MaskFormat CutCopyMaskFormat {
421 return cut_copy_mask_format;
424 if (!Enum.IsDefined (typeof (MaskFormat), value)) {
425 throw new InvalidEnumArgumentException ("value", (int)value, typeof (MaskFormat));
427 cut_copy_mask_format = value;
431 [DesignerSerializationVisibility (DesignerSerializationVisibility.Hidden)]
433 public IFormatProvider FormatProvider {
435 return format_provider;
438 format_provider = value;
442 [RefreshProperties (RefreshProperties.Repaint)]
443 [DefaultValue (false)]
444 public bool HidePromptOnLeave {
446 return hide_prompt_on_leave;
449 hide_prompt_on_leave = value;
453 [DefaultValue (InsertKeyMode.Default)]
454 public InsertKeyMode InsertKeyMode {
456 return insert_key_mode;
459 if (!Enum.IsDefined (typeof (InsertKeyMode), value)) {
460 throw new InvalidEnumArgumentException ("value", (int)value, typeof (InsertKeyMode));
462 insert_key_mode = value;
467 public bool IsOverwriteMode {
469 if (insert_key_mode == InsertKeyMode.Default) {
470 return insert_key_overwriting;
472 return insert_key_mode == InsertKeyMode.Overwrite;
477 [EditorBrowsable (EditorBrowsableState.Never)]
478 [DesignerSerializationVisibility (DesignerSerializationVisibility.Hidden)]
480 public new string [] Lines {
483 if (text == null || text == string.Empty)
484 return new string [] {};
486 return Text.Split (new string [] {"\r\n", "\r", "\n"}, StringSplitOptions.None);
489 // Do nothing, not supported by MTB.
494 [Editor ("System.Windows.Forms.Design.MaskPropertyEditor, " + Consts.AssemblySystem_Design, typeof (UITypeEditor))]
495 [RefreshProperties (RefreshProperties.Repaint)]
502 return provider.Mask;
505 is_empty_mask = (value == string.Empty || value == null);
510 provider = new MaskedTextProvider (value, provider.Culture, provider.AllowPromptAsInput, provider.PromptChar, provider.PasswordChar, provider.AsciiOnly);
511 UpdateVisibleText ();
516 public bool MaskCompleted {
518 return provider.MaskCompleted;
523 [DesignerSerializationVisibility (DesignerSerializationVisibility.Hidden)]
524 public MaskedTextProvider MaskedTextProvider {
529 return provider.Clone () as MaskedTextProvider;
534 public bool MaskFull {
536 return provider.MaskFull;
540 [DesignerSerializationVisibility (DesignerSerializationVisibility.Hidden)]
542 [EditorBrowsable (EditorBrowsableState.Never)]
543 public override int MaxLength {
545 return base.MaxLength;
548 // Do nothing, MTB doesn't support this.
552 [EditorBrowsable (EditorBrowsableState.Never)]
554 [DesignerSerializationVisibility (DesignerSerializationVisibility.Hidden)]
555 public override bool Multiline {
560 // Do nothing, MTB doesn't support this.
564 [RefreshProperties (RefreshProperties.Repaint)]
565 [DefaultValue ('\0')]
566 public char PasswordChar {
568 return provider.PasswordChar;
571 provider.PasswordChar = value;
572 UpdateVisibleText ();
578 [RefreshProperties (RefreshProperties.Repaint)]
579 public char PromptChar {
581 return provider.PromptChar;
584 provider.PromptChar = value;
585 UpdateVisibleText ();
589 public new bool ReadOnly {
591 return base.ReadOnly;
594 base.ReadOnly = value;
598 [DefaultValue (false)]
599 public bool RejectInputOnFirstFailure {
601 return reject_input_on_first_failure;
604 reject_input_on_first_failure = value;
608 [DefaultValue (true)]
609 public bool ResetOnPrompt {
611 return provider.ResetOnPrompt;
614 provider.ResetOnPrompt = value;
618 [DefaultValue (true)]
619 public bool ResetOnSpace {
621 return provider.ResetOnSpace;
624 provider.ResetOnSpace = value;
628 public override string SelectedText {
630 return base.SelectedText;
633 base.SelectedText = value;
634 UpdateVisibleText ();
638 [DefaultValue (true)]
639 public bool SkipLiterals {
641 return provider.SkipLiterals;
644 provider.SkipLiterals = value;
649 [Editor ("System.Windows.Forms.Design.MaskedTextBoxTextEditor, " + Consts.AssemblySystem_Design, typeof (UITypeEditor))]
651 [RefreshProperties (RefreshProperties.Repaint)]
653 public override string Text {
655 if (is_empty_mask || setting_text)
658 // The base constructor may call Text before we get to create a provider,
659 // so it may be null even though it's not an empty mask.
660 if (provider == null)
663 return provider.ToString ();
670 setting_text = false;
672 InputText (value, true, true);
674 UpdateVisibleText ();
678 [DefaultValue (HorizontalAlignment.Left)]
680 public HorizontalAlignment TextAlign {
685 if (text_align != value) {
686 if (!Enum.IsDefined (typeof (HorizontalAlignment), value)) {
687 throw new InvalidEnumArgumentException ("value", (int) value, typeof (HorizontalAlignment));
690 OnTextAlignChanged (EventArgs.Empty);
696 public override int TextLength {
702 [DefaultValue (MaskFormat.IncludeLiterals)]
703 [RefreshProperties (RefreshProperties.Repaint)]
704 public MaskFormat TextMaskFormat {
706 if (provider.IncludePrompt && provider.IncludeLiterals) {
707 return MaskFormat.IncludePromptAndLiterals;
708 } else if (provider.IncludeLiterals) {
709 return MaskFormat.IncludeLiterals;
710 } else if (provider.IncludePrompt) {
711 return MaskFormat.IncludePrompt;
713 return MaskFormat.ExcludePromptAndLiterals;
717 if (!Enum.IsDefined (typeof (MaskFormat), value)) {
718 throw new InvalidEnumArgumentException ("value", (int)value, typeof (MaskFormat));
721 provider.IncludeLiterals = (value & MaskFormat.IncludeLiterals) == MaskFormat.IncludeLiterals;
722 provider.IncludePrompt = (value & MaskFormat.IncludePrompt) == MaskFormat.IncludePrompt;
726 [DefaultValue (false)]
727 [RefreshProperties (RefreshProperties.Repaint)]
728 public bool UseSystemPasswordChar {
730 return use_system_password_char;
733 use_system_password_char = value;
737 [DefaultValue (null)]
739 public Type ValidatingType {
741 return validating_type;
744 validating_type = value;
747 [DesignerSerializationVisibility (DesignerSerializationVisibility.Hidden)]
749 [EditorBrowsable (EditorBrowsableState.Never)]
750 public new bool WordWrap {
755 // Do nothing, not supported by MTB
759 #region Internal and private members
760 internal override void OnPaintInternal (PaintEventArgs pevent)
762 base.OnPaintInternal (pevent);
763 //pevent.Graphics.FillRectangle (ThemeEngine.Current.ResPool.GetSolidBrush (BackColor), ClientRectangle);
764 //TextRenderer.DrawText (pevent.Graphics, Text, Font, ClientRectangle, ForeColor, TextFormatFlags.SingleLine);
765 //pevent.Handled = true;
768 internal override Color ChangeBackColor (Color backColor)
773 private void UpdateVisibleText ()
778 if (base.Text != text) {
779 int selstart = SelectionStart;
781 SelectionStart = selstart;
783 setting_text = false;
786 private void InputText (string text, bool overwrite, bool clear)
795 MaskedTextResultHint resultHint;
798 if (RejectInputOnFirstFailure) {
800 provider.Replace (input, SelectionStart, SelectionStart + SelectionLength, out testPosition, out resultHint);
802 provider.InsertAt (input, SelectionStart);
805 while (!result && input.Length > 0) {
807 result = provider.Replace (input, SelectionStart, SelectionStart + input.Length, out testPosition, out resultHint);
809 result = provider.InsertAt (input, SelectionStart, out testPosition, out resultHint);
816 input = input.Substring (0, Math.Min(testPosition - SelectionStart - 1, input.Length - 1));