# Mask Type: Custom | WPF Controls | DevExpress Documentation

You can use custom masks to specify complex patterns that are difficult to implement via other mask types. Another advantage of custom masks is that you can help users enter correct values. Even if the entered character does not match the mask, you can review the input and transform it into an acceptable value. You can find examples in the sections below.

## Apply a Custom Mask

Do the following to specify a custom mask:

1. Set the editor’s [MaskType](/WPF/DevExpress.Xpf.Editors.TextEdit.MaskType) property to `Custom`.
2. Handle the [CustomMask](/WPF/DevExpress.Xpf.Editors.TextEdit.CustomMask) event.
3. Process the text displayed in the editor ([e.CurrentEditText](/WPF/DevExpress.Xpf.Editors.CustomMaskEventArgs.CurrentEditText)), the text entered by a user ([e.InsertedText](/WPF/DevExpress.Xpf.Editors.CustomMaskEventArgs.InsertedText)), or the edited text ([e.ResultEditText](/WPF/DevExpress.Xpf.Editors.CustomMaskEventArgs.ResultEditText)).
4. Call the [e.SetResult](/WPF/DevExpress.Xpf.Editors.CustomMaskEventArgs.SetResult.overloads) method to specify the editor’s final text. Use the [e.Cancel](/WPF/DevExpress.Xpf.Editors.CustomMaskEventArgs.Cancel) method to prevent text changes.

[Run Demo: Custom Masks](dxdemo://Wpf/DXEditors/MainDemo/CustomMaskEdit)

You can also specify custom masks for editors that operate in [In-Place Mode](/WPF/117648/controls-and-libraries/data-editors/common-features/in-place-mode). To do this, set the **\*EditSettings** object’s [MaskType](/WPF/DevExpress.Xpf.Editors.Settings.TextEditSettings.MaskType) property to `Custom` and attach the [TextEdit.CustomMask](/WPF/DevExpress.Xpf.Editors.TextEdit.CustomMask) event:

- XAML

<section id="tabpanel_vr80fCEtpc_tabid-xaml" role="tabpanel" data-tab="tabid-xaml">
<pre><code data-code-links="{&quot;MaskType&quot;:&quot;/WPF/DevExpress.Xpf.Editors.Settings.TextEditSettings.MaskType&quot;,&quot;CustomMask&quot;:&quot;/WPF/DevExpress.Xpf.Editors.TextEdit.CustomMask&quot;,&quot;CustomMaskEventArgs&quot;:&quot;/WPF/DevExpress.Xpf.Editors.CustomMaskEventArgs&quot;}" class="lang-xaml">&lt;dxg:GridColumn FieldName=&quot;ProductName&quot;&gt;
    &lt;dxg:GridColumn.EditSettings&gt;
        &lt;dxe:TextEditSettings MaskType=&quot;Custom&quot; dxe:TextEdit.CustomMask=&quot;OnCustomMask&quot;/&gt;
    &lt;/dxg:GridColumn.EditSettings&gt;
&lt;/dxg:GridColumn&gt;
</code></pre></section>

- C#
- VB.NET

<section id="tabpanel_vr80fCEtpc-1_tabid-csharp" role="tabpanel" data-tab="tabid-csharp">
<pre><code data-code-links="{&quot;MaskType&quot;:&quot;/WPF/DevExpress.Xpf.Editors.TextEdit.MaskType&quot;,&quot;CustomMask&quot;:&quot;/WPF/DevExpress.Xpf.Editors.TextEdit.CustomMask&quot;,&quot;CustomMaskEventArgs&quot;:&quot;/WPF/DevExpress.Xpf.Editors.CustomMaskEventArgs&quot;}" class="lang-csharp">void OnCustomMask(object sender, DevExpress.Xpf.Editors.CustomMaskEventArgs e) {
    // Process user input.
}
</code></pre></section>
<section id="tabpanel_vr80fCEtpc-1_tabid-vb" role="tabpanel" data-tab="tabid-vb" aria-hidden="true" hidden="hidden">
<pre><code data-code-links="{&quot;MaskType&quot;:&quot;/WPF/DevExpress.Xpf.Editors.TextEdit.MaskType&quot;,&quot;CustomMask&quot;:&quot;/WPF/DevExpress.Xpf.Editors.TextEdit.CustomMask&quot;,&quot;CustomMaskEventArgs&quot;:&quot;/WPF/DevExpress.Xpf.Editors.CustomMaskEventArgs&quot;}" class="lang-vb">Private Sub OnCustomMask(ByVal sender As Object, ByVal e As DevExpress.Xpf.Editors.CustomMaskEventArgs)
    &#39; Process user input.
End Sub
</code></pre></section>

The [CustomMaskEventArgs](/WPF/DevExpress.Xpf.Editors.CustomMaskEventArgs) class contains API that allows you to obtain the initial editor text, the user action that triggered the event, and the result of this action. You can also process the editor’s selected text, caret position, or obtain a transcription of the user action.

## Examples

### Allow Users to Enter Only Predefined Values

The following code sample allows users to enter only valid image file names:

- XAML

<section id="tabpanel_vr80fCEtpc-2_tabid-xaml" role="tabpanel" data-tab="tabid-xaml">
<pre><code data-code-links="{&quot;MaskType&quot;:&quot;/WPF/DevExpress.Xpf.Editors.TextEdit.MaskType&quot;,&quot;CustomMask&quot;:&quot;/WPF/DevExpress.Xpf.Editors.TextEdit.CustomMask&quot;,&quot;CustomMaskEventArgs&quot;:&quot;/WPF/DevExpress.Xpf.Editors.CustomMaskEventArgs&quot;}" class="lang-xaml">&lt;dxe:TextEdit MaskType=&quot;Custom&quot; CustomMask=&quot;OnCustomMask&quot;/&gt;
</code></pre></section>

- C#
- VB.NET

<section id="tabpanel_vr80fCEtpc-3_tabid-csharp" role="tabpanel" data-tab="tabid-csharp">
<pre><code data-code-links="{&quot;MaskType&quot;:&quot;/WPF/DevExpress.Xpf.Editors.TextEdit.MaskType&quot;,&quot;CustomMask&quot;:&quot;/WPF/DevExpress.Xpf.Editors.TextEdit.CustomMask&quot;,&quot;CustomMaskEventArgs&quot;:&quot;/WPF/DevExpress.Xpf.Editors.CustomMaskEventArgs&quot;}" class="lang-csharp">void OnCustomMask(object sender, DevExpress.Xpf.Editors.CustomMaskEventArgs e) {
    var imageExtensions = new string[] {&quot;.jpeg&quot;, &quot;.jpg&quot;, &quot;.png&quot;, &quot;.gif&quot;, &quot;.tiff&quot;, &quot;.tif&quot;, &quot;.bmp&quot;, &quot;.svg&quot;, &quot;.esp&quot;};
    var enteredExtension = Path.GetExtension(e.ResultEditText);

    if (e.ResultEditText.Any(x =&gt; Path.GetInvalidFileNameChars().Contains(x)))
        e.Cancel();

    if (!imageExtensions.Any(x =&gt; x.StartsWith(enteredExtension, System.StringComparison.OrdinalIgnoreCase)))
        e.Cancel();
}
</code></pre></section>
<section id="tabpanel_vr80fCEtpc-3_tabid-vb" role="tabpanel" data-tab="tabid-vb" aria-hidden="true" hidden="hidden">
<pre><code data-code-links="{&quot;MaskType&quot;:&quot;/WPF/DevExpress.Xpf.Editors.TextEdit.MaskType&quot;,&quot;CustomMask&quot;:&quot;/WPF/DevExpress.Xpf.Editors.TextEdit.CustomMask&quot;,&quot;CustomMaskEventArgs&quot;:&quot;/WPF/DevExpress.Xpf.Editors.CustomMaskEventArgs&quot;}" class="lang-vb">Private Sub OnCustomMask(ByVal sender As Object, ByVal e As DevExpress.Xpf.Editors.CustomMaskEventArgs)
    Dim imageExtensions = New String() {&quot;.jpeg&quot;, &quot;.jpg&quot;, &quot;.png&quot;, &quot;.gif&quot;, &quot;.tiff&quot;, &quot;.tif&quot;, &quot;.bmp&quot;, &quot;.svg&quot;, &quot;.esp&quot;}
    Dim enteredExtension = Path.GetExtension(e.ResultEditText)

    If e.ResultEditText.Any(Function(x) Path.GetInvalidFileNameChars().Contains(x)) Then e.Cancel()

    If Not imageExtensions.Any(Function(x) x.StartsWith(enteredExtension, System.StringComparison.OrdinalIgnoreCase)) Then e.Cancel()
End Sub
</code></pre></section>

### Enter Unique Characters Only

The code sample below does not allow users to enter strings that have repeated characters:

- XAML

<section id="tabpanel_vr80fCEtpc-4_tabid-xaml" role="tabpanel" data-tab="tabid-xaml">
<pre><code data-code-links="{&quot;MaskType&quot;:&quot;/WPF/DevExpress.Xpf.Editors.TextEdit.MaskType&quot;,&quot;CustomMask&quot;:&quot;/WPF/DevExpress.Xpf.Editors.TextEdit.CustomMask&quot;,&quot;CustomMaskEventArgs&quot;:&quot;/WPF/DevExpress.Xpf.Editors.CustomMaskEventArgs&quot;}" class="lang-xaml">&lt;dxe:TextEdit MaskType=&quot;Custom&quot; CustomMask=&quot;OnCustomMask&quot;/&gt;
</code></pre></section>

- C#
- VB.NET

<section id="tabpanel_vr80fCEtpc-5_tabid-csharp" role="tabpanel" data-tab="tabid-csharp">
<pre><code data-code-links="{&quot;MaskType&quot;:&quot;/WPF/DevExpress.Xpf.Editors.TextEdit.MaskType&quot;,&quot;CustomMask&quot;:&quot;/WPF/DevExpress.Xpf.Editors.TextEdit.CustomMask&quot;,&quot;CustomMaskEventArgs&quot;:&quot;/WPF/DevExpress.Xpf.Editors.CustomMaskEventArgs&quot;}" class="lang-csharp">void OnCustomMask_1(object sender, DevExpress.Xpf.Editors.CustomMaskEventArgs e) {
    if (e.IsCanceled || e.ActionType == CustomTextMaskInputAction.Init)
        return;
    foreach (var c in e.InsertedText) {
        if (e.CurrentEditText.Contains(c))
            e.Cancel();
    }
}
</code></pre></section>
<section id="tabpanel_vr80fCEtpc-5_tabid-vb" role="tabpanel" data-tab="tabid-vb" aria-hidden="true" hidden="hidden">
<pre><code data-code-links="{&quot;MaskType&quot;:&quot;/WPF/DevExpress.Xpf.Editors.TextEdit.MaskType&quot;,&quot;CustomMask&quot;:&quot;/WPF/DevExpress.Xpf.Editors.TextEdit.CustomMask&quot;,&quot;CustomMaskEventArgs&quot;:&quot;/WPF/DevExpress.Xpf.Editors.CustomMaskEventArgs&quot;}" class="lang-vb">Private Sub OnCustomMask_1(ByVal sender As Object, ByVal e As DevExpress.Xpf.Editors.CustomMaskEventArgs)
    If e.IsCanceled OrElse e.ActionType = CustomTextMaskInputAction.Init Then Return

    For Each c In e.InsertedText
        If e.CurrentEditText.Contains(c) Then e.Cancel()
    Next
End Sub
</code></pre></section>

### Capitalize Entered Characters

The following code sample allows users to enter only Latin letters and capitalizes entered characters:

- XAML

<section id="tabpanel_vr80fCEtpc-6_tabid-xaml" role="tabpanel" data-tab="tabid-xaml">
<pre><code data-code-links="{&quot;MaskType&quot;:&quot;/WPF/DevExpress.Xpf.Editors.TextEdit.MaskType&quot;,&quot;CustomMask&quot;:&quot;/WPF/DevExpress.Xpf.Editors.TextEdit.CustomMask&quot;,&quot;CustomMaskEventArgs&quot;:&quot;/WPF/DevExpress.Xpf.Editors.CustomMaskEventArgs&quot;}" class="lang-xaml">&lt;dxe:TextEdit MaskType=&quot;Custom&quot; CustomMask=&quot;OnCustomMask&quot;/&gt;
</code></pre></section>

- C#
- VB.NET

<section id="tabpanel_vr80fCEtpc-7_tabid-csharp" role="tabpanel" data-tab="tabid-csharp">
<pre><code data-code-links="{&quot;MaskType&quot;:&quot;/WPF/DevExpress.Xpf.Editors.TextEdit.MaskType&quot;,&quot;CustomMask&quot;:&quot;/WPF/DevExpress.Xpf.Editors.TextEdit.CustomMask&quot;,&quot;CustomMaskEventArgs&quot;:&quot;/WPF/DevExpress.Xpf.Editors.CustomMaskEventArgs&quot;}" class="lang-csharp">void OnCustomMask(object sender, DevExpress.Xpf.Editors.CustomMaskEventArgs e) {
    if (e.ActionType == CustomTextMaskInputAction.Init || e.IsCanceled == true)
        return;
    var textInfo = CultureInfo.InvariantCulture.TextInfo;
    if (!Regex.IsMatch(e.InsertedText, @&quot;^[a-zA-Z]+$&quot;) &amp;&amp; e.ActionType == CustomTextMaskInputAction.Insert)
        e.Cancel();
    else e.SetResult(textInfo.ToUpper(e.ResultEditText), e.ResultCursorPosition);
}
</code></pre></section>
<section id="tabpanel_vr80fCEtpc-7_tabid-vb" role="tabpanel" data-tab="tabid-vb" aria-hidden="true" hidden="hidden">
<pre><code data-code-links="{&quot;MaskType&quot;:&quot;/WPF/DevExpress.Xpf.Editors.TextEdit.MaskType&quot;,&quot;CustomMask&quot;:&quot;/WPF/DevExpress.Xpf.Editors.TextEdit.CustomMask&quot;,&quot;CustomMaskEventArgs&quot;:&quot;/WPF/DevExpress.Xpf.Editors.CustomMaskEventArgs&quot;}" class="lang-vb">Private Sub OnCustomMask(ByVal sender As Object, ByVal e As DevExpress.Xpf.Editors.CustomMaskEventArgs)
    If e.ActionType = CustomTextMaskInputAction.Init OrElse e.IsCanceled = True Then Return
    Dim textInfo = CultureInfo.InvariantCulture.TextInfo

    If Not Regex.IsMatch(e.InsertedText, &quot;^[a-zA-Z]+$&quot;) AndAlso e.ActionType = CustomTextMaskInputAction.Insert Then
        e.Cancel()
    Else
        e.SetResult(textInfo.ToUpper(e.ResultEditText), e.ResultCursorPosition)
    End If
End Sub
</code></pre></section>