Avalonia icon indicating copy to clipboard operation
Avalonia copied to clipboard

[Bug] MaskedTextProvider empty Mask throws exception

Open Miniontoby opened this issue 1 month ago • 0 comments

Describe the bug

Basically initially you can just use the MaskedTextBox without a Mask value (will default to string.Empty)

But as soon as you set a Mask and then try to clear it again, then it will throw an exception, which doesn't really make sense as to why... Of course I know the MaskedTextBox is supposed to have a mask value, but still. Please see the context to understand why I need to clear it.

System.ArgumentException: 'The value cannot be an empty string. (Parameter 'mask')'

This exception was originally thrown at this call stack:
    System.ArgumentException.ThrowNullOrEmptyException(string, string) in ArgumentException.cs
    System.ArgumentException.ThrowIfNullOrEmpty(string, string) in ArgumentException.cs
    System.ComponentModel.MaskedTextProvider.MaskedTextProvider(string, System.Globalization.CultureInfo, bool, char, char, bool) in MaskedTextProvider.cs
    Avalonia.Controls.MaskedTextBox.OnPropertyChanged.__UpdateMaskProvider|49_0() in MaskedTextBox.cs
    Avalonia.Controls.MaskedTextBox.OnPropertyChanged(Avalonia.AvaloniaPropertyChangedEventArgs) in MaskedTextBox.cs
    Avalonia.AvaloniaObject.OnPropertyChangedCore(Avalonia.AvaloniaPropertyChangedEventArgs) in AvaloniaObject.cs
    Avalonia.Animation.Animatable.OnPropertyChangedCore(Avalonia.AvaloniaPropertyChangedEventArgs) in Animatable.cs
    Avalonia.AvaloniaObject.RaisePropertyChanged<T>(Avalonia.AvaloniaProperty<T>, Avalonia.Data.Optional<T>, Avalonia.Data.BindingValue<T>, Avalonia.Data.BindingPriority, bool) in AvaloniaObject.cs
    Avalonia.PropertyStore.EffectiveValue<T>.NotifyValueChanged(Avalonia.PropertyStore.ValueStore, Avalonia.StyledProperty<T>, T) in EffectiveValue.cs
    Avalonia.PropertyStore.EffectiveValue<T>.SetAndRaiseCore(Avalonia.PropertyStore.ValueStore, Avalonia.StyledProperty<T>, T, Avalonia.Data.BindingPriority, bool, bool) in EffectiveValue.cs
    ...
    [Call Stack Truncated]

To Reproduce

Use the following MainWindow.axaml file

<Window xmlns="https://github.com/avaloniaui"
		xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
		xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
		xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
		mc:Ignorable="d"
		x:Class="TestProject.MainWindow"
		d:DesignWidth="300" d:DesignHeight="50">

    <MaskedTextBox Name="MyMaskedTextBox" Width="240" Height="35" />

</Window>

And then use the following MainWindow.axaml.cs file

namespace TestProject
{
	public partial class MainWindow : Avalonia.Controls.Window
	{
		public MainWindow() : base()
		{
			InitializeComponent();

			// This is fine
			MyMaskedTextBox.Mask = string.Empty;

			// This is fine
			MyMaskedTextBox.Mask = "00000000000000";

			// This will throw
			MyMaskedTextBox.Mask = string.Empty;
		}
	}
}

And then just run the App/project

Expected behavior

I was expecting Avalonia's version of the MaskedTextBox to behave just like the WinForms one, where when the Mask is cleared, it wouldn't throw on me.

Avalonia version

11.3.9

OS

Windows

Additional context

Basically we're using the same MaskedTextBox for phone numbers and for email, some people prefer communication using phone instead of email. And when we're doing email, we don't want the mask.

Also uhhm the code itself actually is even more dynamic as it reads from an database table which has Properties, which values are dynamic. They can be of value string, integer, csv, boolean or date. And all of those types have different Masks: boolean and csv don't have a mask, but date has, and integer has. So yeah it would be nice if I dont have to add a lot of extra code to make this compatible with Avalonia

Having to use this workaround instead doesnt make sense and is just bulky... And it doesn't work!

try { MyMaskedTextBox.Mask = string.Empty; }
catch { }

And it doesn't even clear the mask...

Oh and switching it out for a normal TextBox sounds like a lot of work for such a little thing...

Miniontoby avatar Nov 27 '25 11:11 Miniontoby