I want to truncate the value of a data bound ObservableProperty in my program. It was my understanding that the OnXXXXXXChanging event (where XXXXXX is the variable name) is supposed to run before the actual value of the ObservableProperty is set.
For Example:
[ObservableProperty]
private string referenceNumber = string.Empty;
Then suppose regardless of what is entered, I want to trim the value of the ObservableProperty down to 10 characters at most. So I implement
partial void OnReferenceNumberChanging(string? oldValue, string newValue)
{
if (newValue.Length > 10)
{
newValue = newValue.Substring(0, 10);
}
}
The challenge is that after this code runs and I interrogate the value of the ReferenceNumber ObservableProperty, it shows all the characters that were entered and not just the 10 the new value was trimmed down to. Am I missing something? Is this not an acceptable location to do this type of validation / modification?
I want to truncate the value of a data bound ObservableProperty in my program. It was my understanding that the OnXXXXXXChanging event (where XXXXXX is the variable name) is supposed to run before the actual value of the ObservableProperty is set.
For Example:
[ObservableProperty]
private string referenceNumber = string.Empty;
Then suppose regardless of what is entered, I want to trim the value of the ObservableProperty down to 10 characters at most. So I implement
partial void OnReferenceNumberChanging(string? oldValue, string newValue)
{
if (newValue.Length > 10)
{
newValue = newValue.Substring(0, 10);
}
}
The challenge is that after this code runs and I interrogate the value of the ReferenceNumber ObservableProperty, it shows all the characters that were entered and not just the 10 the new value was trimmed down to. Am I missing something? Is this not an acceptable location to do this type of validation / modification?
Share Improve this question asked Feb 3 at 21:39 Gee M Ceaser JrGee M Ceaser Jr 1,7913 gold badges25 silver badges59 bronze badges 2 |2 Answers
Reset to default 1I usually let the event complete with the error, allowing the invalid input, but, schedule a post fix-up, e.g.
partial void OnReferenceNumberChanging(string? oldValue, string newValue)
{
if (newValue.Length > 10)
{
Application.Current.MainPage.Dispatcher.Dispatch(() =>
{
ReferenceNumber = ReferenceNumber.Substring(0, 10);
});
}
}
This sort of validation is necessary, because .NET MAUI doesn't appear to have any obvious way of blocking invalid input at the time it occurs.
This pattern is needed for more complex fix-up such as regex pattern mask.
I agree that what you're trying to do seems reasonable but for it to work in that intuitive way the newValue
argument would need to be passed by ref
(and that isn't what it does).
So, as I understand it, you have two goals:
- Limit the length of text that can be typed into the UI.
- Limit the length of programmatic changes, too.
You may want to employ different strategies for each, because input to a control like Entry
changes the visible text first and then invokes the bound property. The MaxLength
property is your friend for this phase because it truncates the input text up front, so you don't get the flicker of the extra character while you react to it on the back end.
<Entry
Text="{Binding ReferenceNumber}"
Placeholder="Reference Number"
MaxLength="{Binding MaxLength}" />
Then, to limit the programmatic changes, the key would be to have a property that is observable (fires PropertyChanged
events) but is not an [ObservableProperty]
.
partial class MainPageViewModel : ObservableObject
{
public int MaxLength { get; } = 10;
public string ReferenceNumber
{
get => _referenceNumber;
set
{
if (value?.Length > MaxLength)
{
value = value.Substring(0, MaxLength);
}
if (!Equals(_referenceNumber, value))
{
_referenceNumber = value ?? string.Empty;
OnPropertyChanged();
}
}
}
string _referenceNumber = string.Empty;
}
Entry
control has theMaxLength
property that would do this trimming up front. Is this option not available in your case? – IV. Commented Feb 3 at 23:35