xamarin - Xamarin 使用错误标签形成行为输入验证
问题描述
我正在开发一个使用大量用户输入的项目。我有一个这样的输入屏幕
我已经设法在没有行为的情况下实现了这一点,但它需要大量代码,所以我想使用行为来获得更多干净、健壮的代码。我看过很多更改条目文本或颜色的教程,但正如我上面提到的,我正在尝试使用错误标签。我什至不确定这是否可能。
更新了@ToolmakerSteve 我还没有尝试任何东西,因为我不知道如何使用视图模型和数据绑定与数据触发器来实现这一点。我正在使用另一种方法来制作这个,其中包含很多混乱的代码。我的 xaml 看起来像这样
<!--Name-->
<Entry
Placeholder="{xct:Translate Name}"
Text="{Binding Name}"
Style="{StaticResource EntryStyle}"/>
<!--Name Error-->
<Label
Text="{Binding NameError}"
Style="{StaticResource ErrorLabel}"
IsVisible="{Binding NameErrorVisibility}"
/>
<!--Email-->
<Entry
Placeholder="{xct:Translate Email}"
Text="{Binding Email}"
Style="{StaticResource EntryStyle}"/>
<!--Email Error-->
<Label
Style="{StaticResource ErrorLabel}"
Text="{Binding EmailError}"
IsVisible="{Binding EmailErrorVisibility}"
/>
<!--Password-->
<Entry
Placeholder="{xct:Translate Password}"
Text="{Binding Password}"
Style="{StaticResource EntryStyle}"/>
<!--Password Error-->
<Label
Style="{StaticResource ErrorLabel}"
Text="{Binding PasswordError}"
IsVisible="{Binding PasswordErrorVisibility}"
/>
<!--Confirmed Password-->
<Entry
Placeholder="{xct:Translate ConfirmedPassword}"
Text="{Binding ConfirmedPass}"
Style="{StaticResource EntryStyle}"/>
<!--Confirmed Password Error-->
<Label
Style="{StaticResource ErrorLabel}"
Text="{Binding ConfirmedPassError}"
IsVisible="{Binding ConfirmedPassErrorVisibility}"
/>
解决方案
邮件也有类似的功能,可以参考以下代码:
<ContentPage.Resources>
<ResourceDictionary>
<Style x:Key="baseStyle"
TargetType="Label">
<Setter Property="XAlign" Value="Start" />
<Setter Property="YAlign" Value="Center" />
<Setter Property="FontSize" Value="Micro" />
<Setter Property="FontAttributes" Value="Italic" />
</Style>
<local:BooleanToObjectConverter x:Key="boolToStyleEmail"
x:TypeArguments="Style">
<local:BooleanToObjectConverter.FalseObject>
<Style TargetType="Label" BasedOn="{StaticResource baseStyle}">
<Setter Property="TextColor" Value="#F44336" />
<Setter Property="Text" Value="Enter a valid email" />
</Style>
</local:BooleanToObjectConverter.FalseObject>
<local:BooleanToObjectConverter.TrueObject>
<Style TargetType="Label" BasedOn="{StaticResource baseStyle}">
<Setter Property="TextColor" Value="#4CAF50" />
<Setter Property="Text" Value="Your email looks good" />
</Style>
</local:BooleanToObjectConverter.TrueObject>
</local:BooleanToObjectConverter>
</ResourceDictionary>
</ContentPage.Resources>
<StackLayout>
<Grid>
<Grid.RowDefinitions>
<RowDefinition />
<RowDefinition />
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto" />
<ColumnDefinition Width="*" />
<ColumnDefinition Width="40" />
</Grid.ColumnDefinitions>
<Entry Grid.Row="0" Grid.Column="1"
Placeholder="Email" >
<Entry.Behaviors>
<local:EmailValidatorBehavior x:Name="emailValidator"/>
</Entry.Behaviors>
</Entry>
<Label Grid.Row="1" Grid.Column="1" Style="{Binding Source={x:Reference emailValidator},
Path=IsValid,
Converter={StaticResource boolToStyleEmail}}" />
</Grid>
</StackLayout>
的代码BooleanToObjectConverter.cs
class BooleanToObjectConverter<T> : IValueConverter
{
public T FalseObject { set; get; }
public T TrueObject { set; get; }
public object Convert(object value, Type targetType,
object parameter, CultureInfo culture)
{
return (bool)value ? this.TrueObject : this.FalseObject;
}
public object ConvertBack(object value, Type targetType,
object parameter, CultureInfo culture)
{
return ((T)value).Equals(this.TrueObject);
}
}
的代码EmailValidatorBehavior.cs
public class EmailValidatorBehavior : Behavior<Entry>
{
const string emailRegex = @"^(?("")("".+?(?<!\\)""@)|(([0-9a-z]((\.(?!\.))|[-!#\$%&'\*\+/=\?\^`\{\}\|~\w])*)(?<=[0-9a-z])@))" +
@"(?(\[)(\[(\d{1,3}\.){3}\d{1,3}\])|(([0-9a-z][-\w]*[0-9a-z]*\.)+[a-z0-9][\-a-z0-9]{0,22}[a-z0-9]))$";
// Creating BindableProperties with Limited write access: http://iosapi.xamarin.com/index.aspx?link=M%3AXamarin.Forms.BindableObject.SetValue(Xamarin.Forms.BindablePropertyKey%2CSystem.Object)
static readonly BindablePropertyKey IsValidPropertyKey = BindableProperty.CreateReadOnly("IsValid", typeof(bool), typeof(NumberValidatorBehavior), false);
public static readonly BindableProperty IsValidProperty = IsValidPropertyKey.BindableProperty;
public bool IsValid
{
get { return (bool)base.GetValue(IsValidProperty); }
private set { base.SetValue(IsValidPropertyKey, value); }
}
protected override void OnAttachedTo(Entry bindable)
{
bindable.TextChanged += HandleTextChanged;
}
void HandleTextChanged(object sender, TextChangedEventArgs e)
{
IsValid = (Regex.IsMatch(e.NewTextValue, emailRegex, RegexOptions.IgnoreCase, TimeSpan.FromMilliseconds(250)));
((Entry)sender).TextColor = IsValid ? Color.Default : Color.Red;
}
protected override void OnDetachingFrom(Entry bindable)
{
bindable.TextChanged -= HandleTextChanged;
}
}
有关更多详细信息,您可以查看:https ://devblogs.microsoft.com/xamarin/behaviors-in-xamarin-forms/ 。
更新:
我认为没有必要将属性 IsValid
与行为分开并将其放在 ViewModel 中。除了在 ValidatorBehavior 中根据属性设置样式外IsValid
,您还可以IsVisible
根据行为中的属性为标签 设置属性IsValid
。
请参考以下代码:
<Label Grid.Row="1" Grid.Column="1" Text="please enter valid email" IsVisible="{Binding Source={x:Reference emailValidator},
Path=IsValid,Converter={StaticResource invertedBoolToBool}}" TextColor="Red" />
笔记:
invertedBoolToBool
是一个 InverseBoolConverter
InverseBoolConverter.cs
public class InvertedBoolConverter : IValueConverter
{
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
{
return !((bool)value);
}
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
{
return value;
}
}
2.在页面的 ResourceDictionary 中添加以下代码:
<local1:InvertedBoolConverter x:Key="invertedBoolToBool" />
上面的文章中也有一个示例,您可以在这里查看:https ://github.com/nishanil/Xamarin.Forms-Samples 。
推荐阅读
- vue.js - AG-Grid Vue 编辑器集成:20.1.0 和 20.2.0 的区别
- c# - 如何在一周中的特定日子执行某些任务?
- python - 如何将 QlistWidget 中的图标项从上到下而不是从左到右插入到小部件或显示中?
- c++ - ADTF no mediadescription for struct type "错误
- django - Django 过滤器中 Q 和 exclude 的区别
- jpa - IntelliJ 2019.1 找不到 persistence.xml(添加到 Project 的 Classpath)
- amazon-web-services - 如何使用 AWS 正确设置私有网页测试实例
- angular - 使用 Karma 测试服务是否已在方法内部更新
- json-server - 如何编写具有多个参数的 JSON-Server 获取调用?
- postgresql - 编写自定义聚合函数