a575963da9
Former-commit-id: da6be194a6b1221998fc28233f2503bd61dd9d14
913 lines
23 KiB
C#
913 lines
23 KiB
C#
//
|
|
// MaskedTextBox.cs
|
|
//
|
|
// Permission is hereby granted, free of charge, to any person obtaining
|
|
// a copy of this software and associated documentation files (the
|
|
// "Software"), to deal in the Software without restriction, including
|
|
// without limitation the rights to use, copy, modify, merge, publish,
|
|
// distribute, sublicense, and/or sell copies of the Software, and to
|
|
// permit persons to whom the Software is furnished to do so, subject to
|
|
// the following conditions:
|
|
//
|
|
// The above copyright notice and this permission notice shall be
|
|
// included in all copies or substantial portions of the Software.
|
|
//
|
|
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
|
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
|
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
|
// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
|
// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
|
// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
|
// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
|
//
|
|
// Copyright (c) 2007 Novell, Inc.
|
|
//
|
|
// Authors:
|
|
// Rolf Bjarne Kvinge (RKvinge@novell.com)
|
|
//
|
|
|
|
|
|
using System;
|
|
using System.Collections;
|
|
using System.ComponentModel;
|
|
using System.Drawing;
|
|
using System.Drawing.Design;
|
|
using System.Globalization;
|
|
using System.Runtime.InteropServices;
|
|
using System.Security.Permissions;
|
|
using System.Windows.Forms;
|
|
|
|
namespace System.Windows.Forms
|
|
{
|
|
[ClassInterface (ClassInterfaceType.AutoDispatch)]
|
|
[ComVisible (true)]
|
|
[DefaultProperty ("Mask")]
|
|
[DefaultEvent ("MaskInputRejected")]
|
|
[Designer ("System.Windows.Forms.Design.MaskedTextBoxDesigner, " + Consts.AssemblySystem_Design)]
|
|
[DefaultBindingProperty ("Text")]
|
|
public class MaskedTextBox : TextBoxBase
|
|
{
|
|
#region Locals
|
|
private MaskedTextProvider provider;
|
|
private bool beep_on_error;
|
|
private IFormatProvider format_provider;
|
|
private bool hide_prompt_on_leave;
|
|
private InsertKeyMode insert_key_mode;
|
|
private bool insert_key_overwriting;
|
|
private bool reject_input_on_first_failure;
|
|
private HorizontalAlignment text_align;
|
|
private MaskFormat cut_copy_mask_format;
|
|
private bool use_system_password_char;
|
|
private Type validating_type;
|
|
private bool is_empty_mask;
|
|
private bool setting_text;
|
|
#endregion
|
|
|
|
#region Events
|
|
static object AcceptsTabChangedEvent = new object ();
|
|
static object IsOverwriteModeChangedEvent = new object ();
|
|
static object MaskChangedEvent = new object ();
|
|
static object MaskInputRejectedEvent = new object ();
|
|
static object MultilineChangedEvent = new object ();
|
|
static object TextAlignChangedEvent = new object ();
|
|
static object TypeValidationCompletedEvent = new object ();
|
|
|
|
// This event is never raised by MaskedTextBox.
|
|
[DesignerSerializationVisibility (DesignerSerializationVisibility.Hidden)]
|
|
[Browsable (false)]
|
|
[EditorBrowsable (EditorBrowsableState.Never)]
|
|
public new event EventHandler AcceptsTabChanged {
|
|
add { Events.AddHandler (AcceptsTabChangedEvent, value);}
|
|
remove { Events.RemoveHandler (AcceptsTabChangedEvent, value);}
|
|
}
|
|
|
|
public event EventHandler IsOverwriteModeChanged {
|
|
add { Events.AddHandler (IsOverwriteModeChangedEvent, value); }
|
|
remove { Events.RemoveHandler (IsOverwriteModeChangedEvent, value); }
|
|
}
|
|
|
|
public event EventHandler MaskChanged {
|
|
add { Events.AddHandler (MaskChangedEvent, value); }
|
|
remove { Events.RemoveHandler (MaskChangedEvent, value); }
|
|
}
|
|
|
|
public event MaskInputRejectedEventHandler MaskInputRejected {
|
|
add { Events.AddHandler (MaskInputRejectedEvent, value); }
|
|
remove { Events.RemoveHandler (MaskInputRejectedEvent, value); }
|
|
}
|
|
|
|
// This event is never raised by MaskedTextBox.
|
|
[DesignerSerializationVisibility (DesignerSerializationVisibility.Hidden)]
|
|
[Browsable (false)]
|
|
[EditorBrowsable (EditorBrowsableState.Never)]
|
|
public new event EventHandler MultilineChanged {
|
|
add { Events.AddHandler (MultilineChangedEvent, value); }
|
|
remove { Events.RemoveHandler (MultilineChangedEvent, value); }
|
|
}
|
|
|
|
public event EventHandler TextAlignChanged {
|
|
add { Events.AddHandler (TextAlignChangedEvent, value); }
|
|
remove { Events.RemoveHandler (TextAlignChangedEvent, value); }
|
|
}
|
|
|
|
public event TypeValidationEventHandler TypeValidationCompleted {
|
|
add { Events.AddHandler (TypeValidationCompletedEvent, value); }
|
|
remove { Events.RemoveHandler (TypeValidationCompletedEvent, value); }
|
|
}
|
|
#endregion
|
|
|
|
#region Constructors
|
|
public MaskedTextBox ()
|
|
{
|
|
provider = new MaskedTextProvider ("<>", CultureInfo.CurrentCulture);
|
|
is_empty_mask = true;
|
|
Init ();
|
|
}
|
|
|
|
public MaskedTextBox (MaskedTextProvider maskedTextProvider)
|
|
{
|
|
if (maskedTextProvider == null) {
|
|
throw new ArgumentNullException ();
|
|
}
|
|
provider = maskedTextProvider;
|
|
is_empty_mask = false;
|
|
Init ();
|
|
}
|
|
|
|
public MaskedTextBox (string mask)
|
|
{
|
|
if (mask == null) {
|
|
throw new ArgumentNullException ();
|
|
}
|
|
provider = new MaskedTextProvider (mask, CultureInfo.CurrentCulture);
|
|
is_empty_mask = false;
|
|
Init ();
|
|
}
|
|
|
|
private void Init ()
|
|
{
|
|
BackColor = SystemColors.Window;
|
|
cut_copy_mask_format = MaskFormat.IncludeLiterals;
|
|
insert_key_overwriting = false;
|
|
UpdateVisibleText ();
|
|
}
|
|
#endregion
|
|
|
|
#region Public and protected methods
|
|
[EditorBrowsable (EditorBrowsableState.Never)]
|
|
public new void ClearUndo ()
|
|
{
|
|
// Do nothing, not supported by MTB
|
|
}
|
|
|
|
[EditorBrowsable (EditorBrowsableState.Advanced)]
|
|
[UIPermission (SecurityAction.InheritanceDemand, Window = UIPermissionWindow.AllWindows)]
|
|
protected override void CreateHandle ()
|
|
{
|
|
base.CreateHandle ();
|
|
}
|
|
|
|
public override char GetCharFromPosition (Point pt)
|
|
{
|
|
return base.GetCharFromPosition (pt);
|
|
}
|
|
|
|
public override int GetCharIndexFromPosition (Point pt)
|
|
{
|
|
return base.GetCharIndexFromPosition (pt);
|
|
}
|
|
|
|
[EditorBrowsable (EditorBrowsableState.Never)]
|
|
public new int GetFirstCharIndexFromLine (int lineNumber)
|
|
{
|
|
return 0;
|
|
}
|
|
|
|
[EditorBrowsable (EditorBrowsableState.Never)]
|
|
public new int GetFirstCharIndexOfCurrentLine ()
|
|
{
|
|
return 0;
|
|
}
|
|
|
|
[EditorBrowsable (EditorBrowsableState.Never)]
|
|
public override int GetLineFromCharIndex (int index)
|
|
{
|
|
return 0;
|
|
}
|
|
|
|
public override Point GetPositionFromCharIndex (int index)
|
|
{
|
|
return base.GetPositionFromCharIndex (index);
|
|
}
|
|
|
|
protected override bool IsInputKey (Keys keyData)
|
|
{
|
|
return base.IsInputKey (keyData);
|
|
}
|
|
|
|
protected override void OnBackColorChanged (EventArgs e)
|
|
{
|
|
base.OnBackColorChanged (e);
|
|
}
|
|
|
|
protected override void OnHandleCreated (EventArgs e)
|
|
{
|
|
base.OnHandleCreated (e);
|
|
}
|
|
|
|
[EditorBrowsable (EditorBrowsableState.Advanced)]
|
|
protected virtual void OnIsOverwriteModeChanged (EventArgs e)
|
|
{
|
|
EventHandler eh = (EventHandler) Events [IsOverwriteModeChangedEvent];
|
|
if (eh != null)
|
|
eh (this, e);
|
|
}
|
|
|
|
protected override void OnKeyDown (KeyEventArgs e)
|
|
{
|
|
// Only handle Delete or Insert here
|
|
|
|
if (e.KeyCode == Keys.Insert && insert_key_mode == InsertKeyMode.Default) {
|
|
// switch the internal overwriting mode, not the public one
|
|
insert_key_overwriting = !insert_key_overwriting;
|
|
OnIsOverwriteModeChanged (EventArgs.Empty);
|
|
e.Handled = true;
|
|
return;
|
|
}
|
|
|
|
if (e.KeyCode != Keys.Delete || is_empty_mask) {
|
|
base.OnKeyDown (e);
|
|
return;
|
|
}
|
|
|
|
int testPosition, endSelection;
|
|
MaskedTextResultHint resultHint;
|
|
bool result;
|
|
|
|
// Use a slightly different approach than the one used for backspace
|
|
endSelection = SelectionLength == 0 ? SelectionStart : SelectionStart + SelectionLength - 1;
|
|
result = provider.RemoveAt (SelectionStart, endSelection, out testPosition, out resultHint);
|
|
|
|
PostprocessKeyboardInput (result, testPosition, testPosition, resultHint);
|
|
|
|
e.Handled = true;
|
|
}
|
|
|
|
protected override void OnKeyPress (KeyPressEventArgs e)
|
|
{
|
|
if (is_empty_mask) {
|
|
base.OnKeyPress (e);
|
|
return;
|
|
}
|
|
|
|
int testPosition, editPosition;
|
|
MaskedTextResultHint resultHint;
|
|
bool result;
|
|
|
|
if (e.KeyChar == '\b') {
|
|
if (SelectionLength == 0)
|
|
result = provider.RemoveAt (SelectionStart - 1, SelectionStart - 1, out testPosition, out resultHint);
|
|
else
|
|
result = provider.RemoveAt (SelectionStart, SelectionStart + SelectionLength - 1, out testPosition, out resultHint);
|
|
|
|
editPosition = testPosition;
|
|
} else if (IsOverwriteMode || SelectionLength > 0) { // Replace
|
|
int start = provider.FindEditPositionFrom (SelectionStart, true);
|
|
int end = SelectionLength > 0 ? SelectionStart + SelectionLength - 1 : start;
|
|
result = provider.Replace (e.KeyChar, start, end, out testPosition, out resultHint);
|
|
|
|
editPosition = testPosition + 1;
|
|
} else {
|
|
// Move chars to the right
|
|
result = provider.InsertAt (e.KeyChar, SelectionStart, out testPosition, out resultHint);
|
|
editPosition = testPosition + 1;
|
|
}
|
|
|
|
PostprocessKeyboardInput (result, editPosition, testPosition, resultHint);
|
|
|
|
e.Handled = true;
|
|
}
|
|
|
|
void PostprocessKeyboardInput (bool result, int newPosition, int testPosition, MaskedTextResultHint resultHint)
|
|
{
|
|
if (!result)
|
|
OnMaskInputRejected (new MaskInputRejectedEventArgs (testPosition, resultHint));
|
|
else {
|
|
if (newPosition != MaskedTextProvider.InvalidIndex)
|
|
SelectionStart = newPosition;
|
|
else
|
|
SelectionStart = provider.Length;
|
|
|
|
UpdateVisibleText ();
|
|
}
|
|
}
|
|
|
|
protected override void OnKeyUp (KeyEventArgs e)
|
|
{
|
|
base.OnKeyUp (e);
|
|
}
|
|
|
|
[EditorBrowsable (EditorBrowsableState.Advanced)]
|
|
protected virtual void OnMaskChanged (EventArgs e)
|
|
{
|
|
EventHandler eh = (EventHandler) Events [MaskChangedEvent];
|
|
if (eh != null)
|
|
eh (this, e);
|
|
}
|
|
|
|
private void OnMaskInputRejected (MaskInputRejectedEventArgs e)
|
|
{
|
|
MaskInputRejectedEventHandler eh = (MaskInputRejectedEventHandler) Events [MaskInputRejectedEvent];
|
|
if (eh != null)
|
|
eh (this, e);
|
|
}
|
|
|
|
[EditorBrowsable (EditorBrowsableState.Never)]
|
|
protected override void OnMultilineChanged (EventArgs e)
|
|
{
|
|
EventHandler eh = (EventHandler)Events [MultilineChangedEvent];
|
|
if (eh != null)
|
|
eh (this, e);
|
|
}
|
|
|
|
protected virtual void OnTextAlignChanged (EventArgs e)
|
|
{
|
|
EventHandler eh = (EventHandler)Events [TextAlignChangedEvent];
|
|
if (eh != null)
|
|
eh (this, e);
|
|
}
|
|
|
|
protected override void OnTextChanged (EventArgs e)
|
|
{
|
|
base.OnTextChanged (e);
|
|
}
|
|
|
|
[EditorBrowsable (EditorBrowsableState.Advanced)]
|
|
protected override void OnValidating (CancelEventArgs e)
|
|
{
|
|
base.OnValidating (e);
|
|
}
|
|
|
|
//[SecurityPermission (SecurityAction.LinkDemand, Flags = SecurityPermissionFlag.UnmanagedCode)]
|
|
protected override bool ProcessCmdKey (ref Message msg, Keys keyData)
|
|
{
|
|
return base.ProcessCmdKey (ref msg, keyData);
|
|
}
|
|
|
|
//[SecurityPermission (SecurityAction.LinkDemand, Flags = SecurityPermissionFlag.UnmanagedCode)]
|
|
protected internal override bool ProcessKeyMessage (ref Message m)
|
|
{
|
|
return base.ProcessKeyMessage (ref m);
|
|
}
|
|
|
|
[EditorBrowsable (EditorBrowsableState.Never)]
|
|
public new void ScrollToCaret ()
|
|
{
|
|
// MSDN: this method is overridden to perform no actions.
|
|
}
|
|
|
|
public override string ToString ()
|
|
{
|
|
return base.ToString () + ", Text: " + provider.ToString (false, false);
|
|
}
|
|
|
|
[EditorBrowsable (EditorBrowsableState.Never)]
|
|
public new void Undo ()
|
|
{
|
|
// Do nothing, not supported by MTB.
|
|
}
|
|
|
|
public object ValidateText ()
|
|
{
|
|
throw new NotImplementedException ();
|
|
}
|
|
|
|
//[SecurityPermission (SecurityAction.LinkDemand, Flags = SecurityPermissionFlag.UnmanagedCode)]
|
|
protected override void WndProc (ref Message m)
|
|
{
|
|
switch ((Msg) m.Msg) {
|
|
default:
|
|
base.WndProc (ref m);
|
|
return;
|
|
}
|
|
}
|
|
#endregion
|
|
|
|
#region Properties
|
|
[EditorBrowsable (EditorBrowsableState.Never)]
|
|
[DesignerSerializationVisibility (DesignerSerializationVisibility.Hidden)]
|
|
[Browsable (false)]
|
|
public new bool AcceptsTab {
|
|
get {
|
|
return false;
|
|
}
|
|
set {
|
|
}
|
|
}
|
|
|
|
[DefaultValue (true)]
|
|
public bool AllowPromptAsInput {
|
|
get {
|
|
return provider.AllowPromptAsInput;
|
|
}
|
|
set {
|
|
provider = new MaskedTextProvider (provider.Mask, provider.Culture, value, provider.PromptChar, provider.PasswordChar, provider.AsciiOnly);
|
|
UpdateVisibleText ();
|
|
}
|
|
}
|
|
|
|
[RefreshProperties (RefreshProperties.Repaint)]
|
|
[DefaultValue (false)]
|
|
public bool AsciiOnly {
|
|
get {
|
|
return provider.AsciiOnly;
|
|
}
|
|
set {
|
|
provider = new MaskedTextProvider (provider.Mask, provider.Culture, provider.AllowPromptAsInput, provider.PromptChar, provider.PasswordChar, value);
|
|
UpdateVisibleText ();
|
|
}
|
|
}
|
|
|
|
[DefaultValue (false)]
|
|
public bool BeepOnError {
|
|
get {
|
|
return beep_on_error;
|
|
}
|
|
set {
|
|
beep_on_error = value;
|
|
}
|
|
}
|
|
|
|
[Browsable (false)]
|
|
[DesignerSerializationVisibility (DesignerSerializationVisibility.Hidden)]
|
|
[EditorBrowsable (EditorBrowsableState.Never)]
|
|
public new bool CanUndo {
|
|
get {
|
|
return false;
|
|
}
|
|
}
|
|
|
|
protected override CreateParams CreateParams {
|
|
//[SecurityPermission (SecurityAction.LinkDemand, Flags = SecurityPermissionFlag.UnmanagedCode)]
|
|
get {
|
|
return base.CreateParams;
|
|
}
|
|
}
|
|
|
|
[RefreshProperties (RefreshProperties.Repaint)]
|
|
public CultureInfo Culture {
|
|
get {
|
|
return provider.Culture;
|
|
}
|
|
set {
|
|
provider = new MaskedTextProvider (provider.Mask, value, provider.AllowPromptAsInput, provider.PromptChar, provider.PasswordChar, provider.AsciiOnly);
|
|
UpdateVisibleText ();
|
|
}
|
|
}
|
|
|
|
[RefreshProperties (RefreshProperties.Repaint)]
|
|
[DefaultValue (MaskFormat.IncludeLiterals)]
|
|
public MaskFormat CutCopyMaskFormat {
|
|
get {
|
|
return cut_copy_mask_format;
|
|
}
|
|
set {
|
|
if (!Enum.IsDefined (typeof (MaskFormat), value)) {
|
|
throw new InvalidEnumArgumentException ("value", (int)value, typeof (MaskFormat));
|
|
}
|
|
cut_copy_mask_format = value;
|
|
}
|
|
}
|
|
|
|
[DesignerSerializationVisibility (DesignerSerializationVisibility.Hidden)]
|
|
[Browsable (false)]
|
|
public IFormatProvider FormatProvider {
|
|
get {
|
|
return format_provider;
|
|
}
|
|
set {
|
|
format_provider = value;
|
|
}
|
|
}
|
|
|
|
[RefreshProperties (RefreshProperties.Repaint)]
|
|
[DefaultValue (false)]
|
|
public bool HidePromptOnLeave {
|
|
get {
|
|
return hide_prompt_on_leave;
|
|
}
|
|
set {
|
|
hide_prompt_on_leave = value;
|
|
}
|
|
}
|
|
|
|
[DefaultValue (InsertKeyMode.Default)]
|
|
public InsertKeyMode InsertKeyMode {
|
|
get {
|
|
return insert_key_mode;
|
|
}
|
|
set {
|
|
if (!Enum.IsDefined (typeof (InsertKeyMode), value)) {
|
|
throw new InvalidEnumArgumentException ("value", (int)value, typeof (InsertKeyMode));
|
|
}
|
|
insert_key_mode = value;
|
|
}
|
|
}
|
|
|
|
[Browsable (false)]
|
|
public bool IsOverwriteMode {
|
|
get {
|
|
if (insert_key_mode == InsertKeyMode.Default) {
|
|
return insert_key_overwriting;
|
|
} else {
|
|
return insert_key_mode == InsertKeyMode.Overwrite;
|
|
}
|
|
}
|
|
}
|
|
|
|
[EditorBrowsable (EditorBrowsableState.Never)]
|
|
[DesignerSerializationVisibility (DesignerSerializationVisibility.Hidden)]
|
|
[Browsable (false)]
|
|
public new string [] Lines {
|
|
get {
|
|
string text = Text;
|
|
if (text == null || text == string.Empty)
|
|
return new string [] {};
|
|
|
|
return Text.Split (new string [] {"\r\n", "\r", "\n"}, StringSplitOptions.None);
|
|
}
|
|
set {
|
|
// Do nothing, not supported by MTB.
|
|
}
|
|
}
|
|
|
|
[Localizable (true)]
|
|
[Editor ("System.Windows.Forms.Design.MaskPropertyEditor, " + Consts.AssemblySystem_Design, typeof (UITypeEditor))]
|
|
[RefreshProperties (RefreshProperties.Repaint)]
|
|
[MergablePropertyAttribute (false)]
|
|
[DefaultValue ("")]
|
|
public string Mask {
|
|
get {
|
|
if (is_empty_mask)
|
|
return string.Empty;
|
|
|
|
return provider.Mask;
|
|
}
|
|
set {
|
|
is_empty_mask = (value == string.Empty || value == null);
|
|
if (is_empty_mask) {
|
|
value = "<>";
|
|
}
|
|
|
|
provider = new MaskedTextProvider (value, provider.Culture, provider.AllowPromptAsInput, provider.PromptChar, provider.PasswordChar, provider.AsciiOnly);
|
|
ReCalculatePasswordChar ();
|
|
UpdateVisibleText ();
|
|
}
|
|
}
|
|
|
|
[Browsable (false)]
|
|
public bool MaskCompleted {
|
|
get {
|
|
return provider.MaskCompleted;
|
|
}
|
|
}
|
|
|
|
[Browsable (false)]
|
|
[DesignerSerializationVisibility (DesignerSerializationVisibility.Hidden)]
|
|
public MaskedTextProvider MaskedTextProvider {
|
|
get {
|
|
if (is_empty_mask)
|
|
return null;
|
|
|
|
return provider.Clone () as MaskedTextProvider;
|
|
}
|
|
}
|
|
|
|
[Browsable (false)]
|
|
public bool MaskFull {
|
|
get {
|
|
return provider.MaskFull;
|
|
}
|
|
}
|
|
|
|
[DesignerSerializationVisibility (DesignerSerializationVisibility.Hidden)]
|
|
[Browsable (false)]
|
|
[EditorBrowsable (EditorBrowsableState.Never)]
|
|
public override int MaxLength {
|
|
get {
|
|
return base.MaxLength;
|
|
}
|
|
set {
|
|
// Do nothing, MTB doesn't support this.
|
|
}
|
|
}
|
|
|
|
[EditorBrowsable (EditorBrowsableState.Never)]
|
|
[Browsable (false)]
|
|
[DesignerSerializationVisibility (DesignerSerializationVisibility.Hidden)]
|
|
public override bool Multiline {
|
|
get {
|
|
return false;
|
|
}
|
|
set {
|
|
// Do nothing, MTB doesn't support this.
|
|
}
|
|
}
|
|
|
|
[RefreshProperties (RefreshProperties.Repaint)]
|
|
[DefaultValue ('\0')]
|
|
public char PasswordChar {
|
|
get {
|
|
if (use_system_password_char)
|
|
return '*';
|
|
|
|
return provider.PasswordChar;
|
|
}
|
|
set {
|
|
provider.PasswordChar = value;
|
|
|
|
if (value != '\0') {
|
|
provider.IsPassword = true;
|
|
} else
|
|
provider.IsPassword = false;
|
|
|
|
ReCalculatePasswordChar (true);
|
|
CalculateDocument ();
|
|
|
|
UpdateVisibleText ();
|
|
}
|
|
}
|
|
|
|
[Localizable (true)]
|
|
[DefaultValue ('_')]
|
|
[RefreshProperties (RefreshProperties.Repaint)]
|
|
public char PromptChar {
|
|
get {
|
|
return provider.PromptChar;
|
|
}
|
|
set {
|
|
provider.PromptChar = value;
|
|
UpdateVisibleText ();
|
|
}
|
|
}
|
|
|
|
public new bool ReadOnly {
|
|
get {
|
|
return base.ReadOnly;
|
|
}
|
|
set {
|
|
base.ReadOnly = value;
|
|
}
|
|
}
|
|
|
|
[DefaultValue (false)]
|
|
public bool RejectInputOnFirstFailure {
|
|
get {
|
|
return reject_input_on_first_failure;
|
|
}
|
|
set {
|
|
reject_input_on_first_failure = value;
|
|
}
|
|
}
|
|
|
|
[DefaultValue (true)]
|
|
public bool ResetOnPrompt {
|
|
get {
|
|
return provider.ResetOnPrompt;
|
|
}
|
|
set {
|
|
provider.ResetOnPrompt = value;
|
|
}
|
|
}
|
|
|
|
[DefaultValue (true)]
|
|
public bool ResetOnSpace {
|
|
get {
|
|
return provider.ResetOnSpace;
|
|
}
|
|
set {
|
|
provider.ResetOnSpace = value;
|
|
}
|
|
}
|
|
|
|
public override string SelectedText {
|
|
get {
|
|
return base.SelectedText;
|
|
}
|
|
set {
|
|
base.SelectedText = value;
|
|
UpdateVisibleText ();
|
|
}
|
|
}
|
|
|
|
[DefaultValue (true)]
|
|
public bool SkipLiterals {
|
|
get {
|
|
return provider.SkipLiterals;
|
|
}
|
|
set {
|
|
provider.SkipLiterals = value;
|
|
}
|
|
}
|
|
|
|
[Bindable (true)]
|
|
[Editor ("System.Windows.Forms.Design.MaskedTextBoxTextEditor, " + Consts.AssemblySystem_Design, typeof (UITypeEditor))]
|
|
[Localizable (true)]
|
|
[RefreshProperties (RefreshProperties.Repaint)]
|
|
[DefaultValue ("")]
|
|
public override string Text {
|
|
get {
|
|
if (is_empty_mask || setting_text)
|
|
return base.Text;
|
|
|
|
// The base constructor may call Text before we get to create a provider,
|
|
// so it may be null even though it's not an empty mask.
|
|
if (provider == null)
|
|
return string.Empty;
|
|
|
|
return provider.ToString ();
|
|
}
|
|
set {
|
|
|
|
if (is_empty_mask) {
|
|
setting_text = true;
|
|
base.Text = value;
|
|
setting_text = false;
|
|
} else {
|
|
InputText (value);
|
|
}
|
|
UpdateVisibleText ();
|
|
}
|
|
}
|
|
|
|
[DefaultValue (HorizontalAlignment.Left)]
|
|
[Localizable (true)]
|
|
public HorizontalAlignment TextAlign {
|
|
get {
|
|
return text_align;
|
|
}
|
|
set {
|
|
if (text_align != value) {
|
|
if (!Enum.IsDefined (typeof (HorizontalAlignment), value)) {
|
|
throw new InvalidEnumArgumentException ("value", (int) value, typeof (HorizontalAlignment));
|
|
}
|
|
text_align = value;
|
|
OnTextAlignChanged (EventArgs.Empty);
|
|
}
|
|
}
|
|
}
|
|
|
|
[Browsable (false)]
|
|
public override int TextLength {
|
|
get {
|
|
return Text.Length;
|
|
}
|
|
}
|
|
|
|
[DefaultValue (MaskFormat.IncludeLiterals)]
|
|
[RefreshProperties (RefreshProperties.Repaint)]
|
|
public MaskFormat TextMaskFormat {
|
|
get {
|
|
if (provider.IncludePrompt && provider.IncludeLiterals) {
|
|
return MaskFormat.IncludePromptAndLiterals;
|
|
} else if (provider.IncludeLiterals) {
|
|
return MaskFormat.IncludeLiterals;
|
|
} else if (provider.IncludePrompt) {
|
|
return MaskFormat.IncludePrompt;
|
|
} else {
|
|
return MaskFormat.ExcludePromptAndLiterals;
|
|
}
|
|
}
|
|
set {
|
|
if (!Enum.IsDefined (typeof (MaskFormat), value)) {
|
|
throw new InvalidEnumArgumentException ("value", (int)value, typeof (MaskFormat));
|
|
}
|
|
|
|
provider.IncludeLiterals = (value & MaskFormat.IncludeLiterals) == MaskFormat.IncludeLiterals;
|
|
provider.IncludePrompt = (value & MaskFormat.IncludePrompt) == MaskFormat.IncludePrompt;
|
|
}
|
|
}
|
|
|
|
[DefaultValue (false)]
|
|
[RefreshProperties (RefreshProperties.Repaint)]
|
|
public bool UseSystemPasswordChar {
|
|
get {
|
|
return use_system_password_char;
|
|
}
|
|
set {
|
|
if (use_system_password_char != value) {
|
|
use_system_password_char = value;
|
|
|
|
if (use_system_password_char)
|
|
PasswordChar = PasswordChar;
|
|
else
|
|
PasswordChar = '\0';
|
|
}
|
|
}
|
|
}
|
|
|
|
[DefaultValue (null)]
|
|
[Browsable (false)]
|
|
public Type ValidatingType {
|
|
get {
|
|
return validating_type;
|
|
}
|
|
set {
|
|
validating_type = value;
|
|
}
|
|
}
|
|
[DesignerSerializationVisibility (DesignerSerializationVisibility.Hidden)]
|
|
[Browsable (false)]
|
|
[EditorBrowsable (EditorBrowsableState.Never)]
|
|
public new bool WordWrap {
|
|
get {
|
|
return false;
|
|
}
|
|
set {
|
|
// Do nothing, not supported by MTB
|
|
}
|
|
}
|
|
#endregion
|
|
#region Internal and private members
|
|
|
|
private void ReCalculatePasswordChar ()
|
|
{
|
|
ReCalculatePasswordChar (PasswordChar != '\0');
|
|
}
|
|
|
|
private void ReCalculatePasswordChar (bool using_password)
|
|
{
|
|
if (using_password)
|
|
if (is_empty_mask)
|
|
document.PasswordChar = PasswordChar.ToString ();
|
|
else
|
|
document.PasswordChar = string.Empty;
|
|
}
|
|
|
|
internal override void OnPaintInternal (PaintEventArgs pevent)
|
|
{
|
|
base.OnPaintInternal (pevent);
|
|
//pevent.Graphics.FillRectangle (ThemeEngine.Current.ResPool.GetSolidBrush (BackColor), ClientRectangle);
|
|
//TextRenderer.DrawText (pevent.Graphics, Text, Font, ClientRectangle, ForeColor, TextFormatFlags.SingleLine);
|
|
//pevent.Handled = true;
|
|
}
|
|
|
|
internal override Color ChangeBackColor (Color backColor)
|
|
{
|
|
return backColor;
|
|
}
|
|
|
|
private void UpdateVisibleText ()
|
|
{
|
|
string text = null;
|
|
|
|
if (is_empty_mask || setting_text)
|
|
text = base.Text;
|
|
else
|
|
if (provider == null)
|
|
text = string.Empty;
|
|
else
|
|
text = provider.ToDisplayString ();
|
|
|
|
setting_text = true;
|
|
if (base.Text != text) {
|
|
int selstart = SelectionStart;
|
|
base.Text = text;
|
|
SelectionStart = selstart;
|
|
}
|
|
setting_text = false;
|
|
}
|
|
|
|
private void InputText (string text)
|
|
{
|
|
string input = text;
|
|
|
|
int testPosition;
|
|
MaskedTextResultHint resultHint;
|
|
bool result;
|
|
|
|
if (RejectInputOnFirstFailure) {
|
|
result = provider.Set (input, out testPosition, out resultHint);
|
|
if (!result)
|
|
OnMaskInputRejected (new MaskInputRejectedEventArgs (testPosition, resultHint));
|
|
} else {
|
|
provider.Clear ();
|
|
testPosition = 0;
|
|
|
|
// Unfortunately we can't break if we reach the end of the mask, since
|
|
// .net iterates over _all_ the chars in the input
|
|
for (int i = 0; i < input.Length; i++) {
|
|
char c = input [i];
|
|
|
|
result = provider.InsertAt (c, testPosition, out testPosition, out resultHint);
|
|
if (result)
|
|
testPosition++; // Move to the next free position
|
|
else
|
|
OnMaskInputRejected (new MaskInputRejectedEventArgs (testPosition, resultHint));
|
|
}
|
|
}
|
|
}
|
|
#endregion
|
|
}
|
|
}
|