How to: Register a Custom Mask
- 8 minutes to read
You can add a custom mask if your scenario requires a mask that you cannot create with DevExpress mask placeholders, or you need to modify the mask input behavior. To add a custom mask, you need to create and register it. Note that this article does not explain how to create masks.
Registration allows you to resolve the following custom mask issues:
- If users can invoke the Mask Settings dialog at runtime, this dialog does not display custom masks.
- If an editor with a custom mask is used as a cell editor inside a data-aware control (for example, Data Grid), the editor’s mask does not match the mask inside standard control tools (for instance, filters). For example, when an in-place editor shows the date range “Date1 - Date2” mask, an exception is raised when users attempt to invoke the filter because the built-in DateTime column filter does not support this data type.
Follow the steps below to register a custom mask.
In your custom MaskManager implementation, create a custom method that calls the static
DevExpress.Data.Mask.MaskManager.RegisterMaskManagerType
method. This custom method should be called on the application startup.MyDecimalMaskManager.Register(); public class MyDecimalMaskManager : MaskManager { public static void Register() { string signature = typeof(MyDecimalMaskManager).Assembly.GetName().Name + ", " + typeof(MyDecimalMaskManager).FullName; RegisterMaskManagerType(signature, typeof(MyDecimalMaskManager), signature); } // ... }
Decorate a custom MaskManager constructor with the
Parameters
attribute. This attribute allows you to set up default values for required mask properties. The first attribute parameter is the custom mask signature (type name), and the second is the public name of this custom mask in the Mask Settings dialog.public class MyDecimalMaskManager : MaskManager { // ... [Parameters("MyApplication1, MyApplication1.MyDecimalMaskManager", "Double Precision Decimal", "allowNull", false)] public MyDecimalMaskManager( string mask, CultureInfo cultureInfo, bool allowNull) : this(new NumericMaskManager(mask, cultureInfo, allowNull)) { } // ... }
Note that instead of setting default property values with this attribute, you can also set in inside the custom MaskManager constructor (the parameter is then considered as optional)…
[Parameters("MyApplication1, MyApplication1.MyDecimalMaskManager", "Double Precision Decimal")] public MyDecimalMaskManager( string mask, CultureInfo cultureInfo, bool allowNull = false) : this(new NumericMaskManager(mask, cultureInfo, allowNull)) { }
…or decorate these properties with the
DefaultValue
attribute.Decorate properties or constructor parameters with the
Parameter
atrribute. This attribute allows you to:Set an alias for the parameter. For example, the following code assigns the “culture” alias for the “cultureInfo” parameter.
Choose whether the corresponding setting should be visible in the Mask Settings dialog (the “Visibility” parameter), and assign its public name.
Assign a value converter for a property or constructor parameter. For example, the code below allows the “cultureInfo” constructor parameter to utilize the System.ComponentModel.CultureInfoConverter to transform string culture names (“en-US”, “ar-PS”, etc.) to
CultureInfo
objects and back.
You can use multiple
Parameter
attributes with different aliases for the same property. This allows you to choose aliases depending on input values.Editors limited to the specific data type show masks for this specific type only in the Mask Setting dialog. For instance, a SpinEdit can display only numbers, and hides other mask types (Date Time, Regex, etc.)
Custom masks are also not available in the Mask Settings dialog. To display them, decorate your custom MaskManager with the
Compatible
attribute. The attribute parameter should reference the standard MaskManager type this editor uses (for instance, “NumericMaskManager” for a Spin Edit, or “DateTimeMaskManager” for a Date Edit).Decorate alternative MaskManager constructors with the
Ignore
attribute to hide them from the dependency injector.[Ignore] public MyDecimalMaskManager(MaskManager _manager) { this.CoreManager = _manager; this.CoreManager.EditTextChanged += new EventHandler(Nested_EditTextChanged); this.CoreManager.EditTextChanging += new MaskChangingEventHandler(Nested_EditTextChanging); this.CoreManager.LocalEditAction += new CancelEventHandler(Nested_LocalEditAction); }
#Apply a Custom Mask
To apply masks (standard and custom), call the MaskSettings.Configure
method and specify its type. For custom masks, declare a custom MaskSettings.User
descendant.
public abstract class CustomMaskSettings : MaskSettings.User {
public class Decimal : MaskSettingsWithCulture {
protected override Type GetMaskManagerType() {
return typeof(MyDecimalMaskManager);
}
}
}
// apply the custom mask
var settings = spinEdit.MaskSettings.Configure<CustomMaskSettings.Decimal>();
settings.MaskExpression = "#################0\\.00";
This routine allows you to create API for custom mask properties. For example, the code below illustrates how to declare and use the “Precision” property that allows users to set the number of digits after the separator.
Note
This code disables the standard Mask
public abstract class CustomMaskSettings : MaskSettings.User {
public class Decimal : MaskSettingsWithCulture {
protected override Type GetMaskManagerType() {
return typeof(MyDecimalMaskManager);
}
public int Precision {
get { return GetValue("alias", 2); }
set { SetValue("alias", value); }
}
[EditorBrowsable(EditorBrowsableState.Never)]
public new string MaskExpression {
get { return base.MaskExpression; }
set { }
}
}
}
// usage
var settings = spinEdit.MaskSettings.Configure<CustomMaskSettings.Decimal>();
settings.Precision = 3;
In the MaskManager constructor, you need to declare a parameter that corresponds to your custom property. The Parameter
attribute specifies the injection point and allows you to set the property alias.
[Compatible(typeof(NumericMaskManager))]
public class MyDecimalMaskManager : MaskManager {
// ...
[Parameters("MyApplication, MyApplication.MyDecimalMaskManager", "Decimal (Variable Precision)")]
public MyDecimalMaskManager(
[Parameter("culture", typeof(CultureInfoConverter), "Culture (name)", Visibility = ParameterVisibility.Advanced)]
CultureInfo cultureInfo,
[Parameter("alias", "Set Precision")]
int precision=2)
: this(new NumericMaskManager("#####0\\." + new string('0', precision), cultureInfo, false)) {
}
}
The figure below illustrates the Mask Settings dialog for this custom mask.
#Demo
The DevExpress Demo Center includes the “Date Ranges (Custom Mask)” module that demonstrates how to register the custom “Date Range” mask.