I'm trying to support a postal code textbox using the MaskedTextInput and was wondering if it was possible to databind to the mask property?
The logic is so:
The logic is so:
- Initially the textblock is blank so the mask would allow one number or letter.
- If the first digit entered is a letter we dynamically change the mask to Canadian postal code (A#A #A#)
- Otherwise it's a USA zip and the mask is #5
Perhaps I'm making this too complicated and there's a way to supply a mask in the form of a regex that can accomplish this for me?
6 Answers, 1 is accepted
0
Hi Einar,
Actually you can achieve this scenario in two ways. The first one is to attach to the RadMaskedTextInput's ValueChanged event and update your mask depending on the value entered. The second way is MVVM one. Move the same logic you would have if you were using the ValueChanged event approach and call it in a property's setter of your ViewModel.
Hope this helps.
Regards,
Peshito
Telerik
Actually you can achieve this scenario in two ways. The first one is to attach to the RadMaskedTextInput's ValueChanged event and update your mask depending on the value entered. The second way is MVVM one. Move the same logic you would have if you were using the ValueChanged event approach and call it in a property's setter of your ViewModel.
Hope this helps.
Regards,
Peshito
Telerik
Check out the Telerik Platform - the only platform that combines a rich set of UI tools with powerful cloud services to develop web, hybrid and native mobile apps.
0
Einar
Top achievements
Rank 1
answered on 23 Mar 2015, 03:59 PM
If I initially set the mask to a5 I can dynamically change it to #3 and l3 and it prevents the user from entering numbers or letters depending on the mask, however the masks text length doesn't change dynamically (I still see 5 _ characters). As expected you get some buggy behavior by typing in more than 3 characters when the control expects to only have 3.
Additionally the value databinding doesn't appear to invoke the property setter when the value changes if the mask expects letters, but when I have it set to numbers I was notified every time I typed or deleted a number.
Note that I am binding to the Value and Mask properties.
Additionally the value databinding doesn't appear to invoke the property setter when the value changes if the mask expects letters, but when I have it set to numbers I was notified every time I typed or deleted a number.
Note that I am binding to the Value and Mask properties.
0
Hello Einar,
The databinding does not invoke the property setter on every letter typed when a mask is for instance like "A5". In this case the value is updated on every 5th symbol entered. This is how the control is designed and this behavior is expected. Using mask starting with small letter like "a5" however will invoke the setter on each input.
As for the question about the dynamic change of the mask the scenario is complex and it is not supported out of the box as there are a lot of events and methods called after value is entered and in this specific scenario the Mask is being changed in a moment when not all calculations are made. In order to workaround this, a Dispatcher can be used after attaching to the ValueChanged event. This is approach is shown in the attached sample project.
Regards,
Peshito
Telerik
The databinding does not invoke the property setter on every letter typed when a mask is for instance like "A5". In this case the value is updated on every 5th symbol entered. This is how the control is designed and this behavior is expected. Using mask starting with small letter like "a5" however will invoke the setter on each input.
As for the question about the dynamic change of the mask the scenario is complex and it is not supported out of the box as there are a lot of events and methods called after value is entered and in this specific scenario the Mask is being changed in a moment when not all calculations are made. In order to workaround this, a Dispatcher can be used after attaching to the ValueChanged event. This is approach is shown in the attached sample project.
private void tbClid_ValueChanged(object sender, Telerik.Windows.RadRoutedEventArgs e)
{
var value = (sender as RadMaskedTextInput).Value;
if (value.ToString().StartsWith("3"))
{
ChangeMaskDispatched("#3");
}
else if (value.ToString().StartsWith("5"))
{
ChangeMaskDispatched("#5");
}
}
private void ChangeMaskDispatched(string newMASK)
{
Dispatcher.BeginInvoke(new Action(() => tbClid.Mask = newMASK));
}
Regards,
Peshito
Telerik
See What's Next in App Development. Register for TelerikNEXT.
0
Einar
Top achievements
Rank 1
answered on 24 Mar 2015, 05:44 PM
Peshito,
Thanks for the code example. it seems to work fairly well. However, we run into issues when switching between masks.
I've added a condition to your code that says "if the value is null or empty then reset the mask" (so that I can allow the user to switch back and forth between the masks). It correctly works if I enter 3 numbers, backspace them all out and then the mask changes to "#5", however once the mask changes the control stops reporting its value changed on each character change and therefore when I backspace all the characters out in the second mask I don't hit the condition to reset the mask once again.
Note that in my specific use case I start with an alpha numeric mask and then conditionally switch to an all numeric or alphanumeric mask based on a Canadian postal code. (L1#1L1 #1L1#1)
private string _lastVal;
private void RadMaskedInputBase_OnValueChanged(object sender, RadRoutedEventArgs e)
{
var control = (sender as RadMaskedTextInput);
var value = control.Value;
//Cache the last value as resetting the mask at the wrong time causes issues
if (string.IsNullOrWhiteSpace(value) && !string.IsNullOrWhiteSpace(_lastVal))
{
ChangeMaskDispatched("a5");
_lastVal = value;
return;
}
if (Char.IsNumber(value[0]))
{
ChangeMaskDispatched("#5");
}
else if (Char.IsLetter(value[0]))
{
ChangeMaskDispatched("L1#1L1 #1L1#1");
}
_lastVal = value;
}
private void ChangeMaskDispatched(string newMASK)
{
Dispatcher.BeginInvoke(new Action(() => PostalCodeMasked.Mask = newMASK));
}
Thanks for the code example. it seems to work fairly well. However, we run into issues when switching between masks.
I've added a condition to your code that says "if the value is null or empty then reset the mask" (so that I can allow the user to switch back and forth between the masks). It correctly works if I enter 3 numbers, backspace them all out and then the mask changes to "#5", however once the mask changes the control stops reporting its value changed on each character change and therefore when I backspace all the characters out in the second mask I don't hit the condition to reset the mask once again.
Note that in my specific use case I start with an alpha numeric mask and then conditionally switch to an all numeric or alphanumeric mask based on a Canadian postal code. (L1#1L1 #1L1#1)
private string _lastVal;
private void RadMaskedInputBase_OnValueChanged(object sender, RadRoutedEventArgs e)
{
var control = (sender as RadMaskedTextInput);
var value = control.Value;
//Cache the last value as resetting the mask at the wrong time causes issues
if (string.IsNullOrWhiteSpace(value) && !string.IsNullOrWhiteSpace(_lastVal))
{
ChangeMaskDispatched("a5");
_lastVal = value;
return;
}
if (Char.IsNumber(value[0]))
{
ChangeMaskDispatched("#5");
}
else if (Char.IsLetter(value[0]))
{
ChangeMaskDispatched("L1#1L1 #1L1#1");
}
_lastVal = value;
}
private void ChangeMaskDispatched(string newMASK)
{
Dispatcher.BeginInvoke(new Action(() => PostalCodeMasked.Mask = newMASK));
}
0
Accepted
Hi Einar,
I am glad the workaround worked well.
As for the last issue you hit with being unable to attach to ValueChanged event in this scenario, it is actually expected. This is so, because the ""L1#1L1 #1L1#1" is required mask where empty strings or null values are invalid for this type of mask. The RadMaskedTextInput exposes a property called AllowInvalidValues. Setting it to True will allow you to enter the invalid symbol and therefore it will fire the ValueChanged event. I just tried it using the code snipped you shared and it worked well.
Regards,
Peshito
Telerik
I am glad the workaround worked well.
As for the last issue you hit with being unable to attach to ValueChanged event in this scenario, it is actually expected. This is so, because the ""L1#1L1 #1L1#1" is required mask where empty strings or null values are invalid for this type of mask. The RadMaskedTextInput exposes a property called AllowInvalidValues. Setting it to True will allow you to enter the invalid symbol and therefore it will fire the ValueChanged event. I just tried it using the code snipped you shared and it worked well.
Regards,
Peshito
Telerik
See What's Next in App Development. Register for TelerikNEXT.
0
Einar
Top achievements
Rank 1
answered on 25 Mar 2015, 04:08 PM
Peshito,
AllowInvalidValues was indeed the missing piece to this. Thanks so much for your help!
AllowInvalidValues was indeed the missing piece to this. Thanks so much for your help!