Skip to content

Instantly share code, notes, and snippets.

@noelheesen
Created April 24, 2017 14:02
Show Gist options
  • Save noelheesen/a0ce7d27d3fb8038dad117ffafaf270e to your computer and use it in GitHub Desktop.
Save noelheesen/a0ce7d27d3fb8038dad117ffafaf270e to your computer and use it in GitHub Desktop.
GC Loop
namespace MySolution.ValueConverters
{
public class NullableIntConverter : IValueConverter
{
public object Convert(object value, Type targetType, object parameter, CultureInfo culture) {
return value;
}
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture) {
int result;
int.TryParse(value as string, out result);
return result <= 0 ? null : result as int?;
}
}
public class RegexValidator : EventToCommand<View>
{
public static readonly BindableProperty RegularExpressionProperty =
BindableProperty.Create("RegularExpression", typeof(string), typeof(RegexValidator));
public string RegularExpression {
get { return (string)GetValue(RegularExpressionProperty); }
set { SetValue(RegularExpressionProperty, value); }
}
/* Scenario: new value is 'null', old value is '0'
* null is not a match in the regex so it would set the text to 0 triggering the regex validation again.
* Because the ValueConverter is changing 0 to null the regex is triggered again.
* Infinity...
* */
protected override void OnEvent(object sender, object eventArgs) {
string text =
(eventArgs as TextChangedEventArgs)?.NewTextValue
?? (sender as Entry)?.Text
?? (sender as Editor)?.Text;
/* Solution */
if (Equals(text, null))
return;
/* End Solution */
string oldValue = (eventArgs as TextChangedEventArgs)?.OldTextValue;
if (!Equals(text, oldValue) && !this.IsMatch(text)) {
base.OnEvent(sender, eventArgs);
this.SetText(oldValue);
}
}
bool IsMatch(string value) {
return (!Equals(input, null) && Regex.IsMatch(input, this.RegularExpression, RegexOptions.None));
}
void SetText(object sender, string value) {
if (sender is Entry) {
((Entry)sender).Text = value;
} else if (sender is Editor) {
((Editor)sender).Text = value;
} else {
throw new ArgumentException("The RegexValidator can only be applied to an Entry or Editor control");
}
}
}
}
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
xmlns:behaviors="clr-namespace:MySolution.Behaviors"
xmlns:converters="clr-namespace:MySolution.ValueConverters"
x:Class="MySolution.MyClass"
Title="MyTitle">
<ContentPage.Resources>
<ResourceDictionary>
<converters:NullableIntConverter x:Key="NullableIntConverter" />
</ResourceDictionary>
</ContentPage.Resources>
<ContentPage.Content>
<Entry
Text="{Binding MyNullableProperty, Converter={StaticResource NullableIntConverter}}">
<Entry.Behaviors>
<behaviors:NumericValidator />
<behaviors:NumberRangeValidator MinValue="1" MaxValue="999" />
<behaviors:MaxLengthValidator MaxLength="3" />
<behaviors:CursorToEndBehavior />
<behaviors:RegexValidator
RegularExpression="^([1-9]*|[1-9]+[0-9]*)$"
EventName="TextChanged" />
<behaviors:EventToCommand
EventName="Unfocused"
Command="{Binding SaveOnEventCommand}"/>
</Entry.Behaviors>
</Entry>
</ContentPage.Content>
</ContentPage>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment