| File: System\Windows\Forms\Design\MaskDescriptor.cs | Web Access |
| Project: src\winforms\src\System.Windows.Forms.Design\src\System.Windows.Forms.Design.csproj (System.Windows.Forms.Design) |
// Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. using System.ComponentModel; using System.Globalization; namespace System.Windows.Forms.Design; /// <summary> /// MaskDescriptor abstract class defines the set of methods mask descriptors need to implement for the /// MaskedTextBox.Mask UITypeEditor to include as options in the property editor. MaskDescriptor /// types are discovered at designed time by querying the ITypeDiscoveryService service provider from /// the UITypeEditor object. /// </summary> public abstract class MaskDescriptor { /// <summary> /// The mask being described. /// </summary> public abstract string? Mask { get; } /// <summary> /// The friendly name of the mask descriptor. /// Used also as the description for the mask. /// </summary> public abstract string? Name { get; } /// <summary> /// A sample text following the mask specification. /// </summary> public abstract string? Sample { get; } /// <summary> /// A Type representing the type providing validation for this mask. /// </summary> public abstract Type? ValidatingType { get; } /// <summary> /// The CultureInfo representing the locale the mask is designed for. /// </summary> public virtual CultureInfo Culture => Thread.CurrentThread.CurrentCulture; /// <summary> /// Determines whether the specified mask descriptor is valid and hence can be added to the canned masks list. /// A valid MaskDescriptor must meet the following conditions: /// 1. Not null. /// 2. Not null or empty mask. /// 3. Not null or empty name. /// 4. Not null or empty sample. /// 5. The sample is correct based on the mask and all required edit characters have been provided /// (mask completed - not necessarily full). /// 6. The sample is valid based on the ValidatingType object (if any). /// </summary> public static bool IsValidMaskDescriptor([NotNullWhen(true)] MaskDescriptor? maskDescriptor) { return IsValidMaskDescriptor(maskDescriptor, out string _); } public static bool IsValidMaskDescriptor([NotNullWhen(true)] MaskDescriptor? maskDescriptor, out string validationErrorDescription) { validationErrorDescription = string.Empty; if (maskDescriptor is null) { validationErrorDescription = SR.MaskDescriptorNull; return false; } if (string.IsNullOrEmpty(maskDescriptor.Mask) || string.IsNullOrEmpty(maskDescriptor.Name) || string.IsNullOrEmpty(maskDescriptor.Sample)) { validationErrorDescription = SR.MaskDescriptorNullOrEmptyRequiredProperty; return false; } MaskedTextProvider maskedTextProvider = new(maskDescriptor.Mask, maskDescriptor.Culture); MaskedTextBox maskedTextBox = new(maskedTextProvider) { SkipLiterals = true, ResetOnPrompt = true, ResetOnSpace = true, ValidatingType = maskDescriptor.ValidatingType, FormatProvider = maskDescriptor.Culture, Culture = maskDescriptor.Culture }; maskedTextBox.TypeValidationCompleted += maskedTextBox1_TypeValidationCompleted; maskedTextBox.MaskInputRejected += maskedTextBox1_MaskInputRejected; // Add sample. If it fails we are done. maskedTextBox.Text = maskDescriptor.Sample; if (maskedTextBox.Tag is null) // Sample was added successfully (MaskInputRejected event handler did not change the maskedTextBox tag). { if (maskDescriptor.ValidatingType is not null) { maskedTextBox.ValidateText(); } } if (maskedTextBox.Tag is not null) // Validation failed. { validationErrorDescription = maskedTextBox.Tag.ToString()!; } return validationErrorDescription.Length == 0; } private static void maskedTextBox1_MaskInputRejected(object? sender, MaskInputRejectedEventArgs e) { MaskedTextBox maskedTextBox = (MaskedTextBox)sender!; maskedTextBox.Tag = MaskedTextBoxDesigner.GetMaskInputRejectedErrorMessage(e); } private static void maskedTextBox1_TypeValidationCompleted(object? sender, TypeValidationEventArgs e) { if (e.IsValidInput) { return; } MaskedTextBox maskedTextBox = (MaskedTextBox)sender!; maskedTextBox.Tag = e.Message; } /// <summary> /// Determines whether this mask descriptor and the passed object describe the same mask. /// True if the following conditions are met in both, this and the passed object: /// 1. Mask property is the same. /// 2. Validating type is the same /// Observe that the Name property is not considered since MaskedTextProvider/Box are not aware of it. /// </summary> public override bool Equals(object? maskDescriptor) { MaskDescriptor? descriptor = maskDescriptor as MaskDescriptor; if (!IsValidMaskDescriptor(descriptor) || !IsValidMaskDescriptor(this)) { return this == maskDescriptor; // shallow comparison. } return ((Mask == descriptor.Mask) && (ValidatingType == descriptor.ValidatingType)); } public override int GetHashCode() { string hash = string.Concat(Mask, ValidatingType?.ToString()); return hash.GetHashCode(); } public override string ToString() { return $"{GetType()}<Name={Name ?? "null"}, Mask={Mask ?? "null"}, ValidatingType={(ValidatingType is not null ? ValidatingType.ToString() : "null")}"; } }