我为Android定制了Xamarin Forms Entry控件,
我正在使用MVVM Validation通过MVVM验证我的输入,并为每个表单元素生成一条消息。
Validator.AddRequiredRule(() => UserName, Messages.FieldCannotBlank);
Validator.AddRequiredRule(() => Password, Messages.FieldCannotBlank);
我使用的自定义条目是Xlabs的扩展条目的扩展版本。这是条目的代码
public class ExtendedEntry : Entry
{
public ExtendedEntry()
{
BorderColor = Color.Default;
BGColorForRounded = Color.Default;
}
#region XAlign
/// <summary>
/// The XAlign property
/// </summary>
public static readonly BindableProperty XAlignProperty =
BindableProperty.Create(nameof(XAlign), typeof(TextAlignment), typeof(ExtendedEntry),
TextAlignment.Start);
/// <summary>
/// Gets or sets the X alignment of the text
/// </summary>
public TextAlignment XAlign
{
get { return (TextAlignment)GetValue(XAlignProperty); }
set { SetValue(XAlignProperty, value); }
}
#endregion
#region BGColorForRounded
public static BindableProperty BGColorForRoundedProperty =
BindableProperty.Create(nameof(BGColorForRounded), typeof(Color), typeof(ExtendedEntry), default(Color));
public Color BGColorForRounded
{
get { return (Color)GetValue(BGColorForRoundedProperty); }
set { SetValue(BGColorForRoundedProperty, value); }
}
#endregion
#region Padding
public static BindableProperty PaddingProperty =
BindableProperty.Create(nameof(Padding), typeof(Thickness), typeof(ExtendedEntry), default(Thickness), defaultBindingMode: BindingMode.OneWay);
public Thickness Padding
{
get { return (Thickness)GetValue(PaddingProperty); }
set { SetValue(PaddingProperty, value); }
}
#endregion Padding
#region IsReadOnly
public static readonly BindableProperty IsReadOnlyProperty =
BindableProperty.Create("IsReadOnly", typeof(bool), typeof(ExtendedEntry), false);
public bool IsReadOnly
{
get { return (bool)GetValue(IsReadOnlyProperty); }
set { SetValue(IsReadOnlyProperty, value); }
}
#endregion
#region IsValid
public static readonly BindableProperty IsValidProperty =
BindableProperty.Create("IsValid", typeof(bool), typeof(ExtendedEntry), true);
public bool IsValid
{
get { return (bool)GetValue(IsValidProperty); }
set { SetValue(IsValidProperty, value); }
}
#endregion
#region ErrorHint
public static readonly BindableProperty ErrorHintProperty =
BindableProperty.Create("ErrorHint", typeof(string), typeof(ExtendedEntry), "");
public string ErrorHint
{
get { return (string)GetValue(ErrorHintProperty); }
set { SetValue(ErrorHintProperty, value); }
}
#endregion
#region PlaceholderTextColor
/// <summary>
/// The PlaceholderTextColor property
/// </summary>
public static readonly BindableProperty PlaceholderTextColorProperty =
BindableProperty.Create("PlaceholderTextColor", typeof(Color), typeof(ExtendedEntry), Color.Default);
/// <summary>
/// Sets color for placeholder text
/// </summary>
public Color PlaceholderTextColor
{
get { return (Color)GetValue(PlaceholderTextColorProperty); }
set { SetValue(PlaceholderTextColorProperty, value); }
}
#endregion
#region HasBorder
/// <summary>
/// The HasBorder property
/// </summary>
public static readonly BindableProperty HasBorderProperty =
BindableProperty.Create("HasBorder", typeof(bool), typeof(ExtendedEntry), true);
/// <summary>
/// Gets or sets if the border should be shown or not
/// </summary>
public bool HasBorder
{
get { return (bool)GetValue(HasBorderProperty); }
set { SetValue(HasBorderProperty, value); }
}
#endregion
#region BorderRadius
public int BorderRadius
{
get { return (int)GetValue(BorderRadiusProperty); }
set { SetValue(BorderRadiusProperty, value); }
}
// Using a DependencyProperty as the backing store for BorderRadius. This enables animation, styling, binding, etc...
public static readonly BindableProperty BorderRadiusProperty =
BindableProperty.Create("BorderRadius", typeof(int), typeof(ExtendedEntry), 0);
#endregion
#region BorderColor
/// <summary>
/// The Border Color Property
/// </summary>
public static readonly BindableProperty BorderColorProperty =
BindableProperty.Create("BorderColor", typeof(Color), typeof(ExtendedEntry), default(Color));
/// <summary>
/// Gets or sets the border color
/// </summary>
public Color BorderColor
{
get { return (Color)GetValue(BorderColorProperty); }
set { SetValue(BorderColorProperty, value); }
}
#endregion
}
每当按下一个按钮时,我都会调用Validators ValidateAll方法来验证我的所有字段
var result = Validator.ValidateAll();
if (!result.IsValid)
{
App.Current.MainPage.DisplayAlert("Error", "The forms has errors, please review the errors and fix them.", "Ok");
}
Errors = result.AsDictionary();
错误是Viewmodel的另一个属性,它基本上是一个字典,它将在验证后保存属性名称和错误的键值对列表。我将此值映射到Xaml中的ExtendedEntry的ErrorHint属性
<controls:ExtendedEntry ErrorHint="{Binding Errors[UserName]}"
IsValid="{Binding Errors[UserName], Converter={StaticResource DictBool},
Mode=TwoWay}"
Placeholder="sallysmith@gmail.com"
Style="{DynamicResource WhiteEntryStandard}"
Text="{Binding UserName}" />
最后,这是Android的实现
private void SetValidityAndHint(ExtendedEntry view)
{
if (!view.IsValid)
{
if (!string.IsNullOrEmpty(view.ErrorHint))
{
Control.Error = view.ErrorHint;
}
}
}
这适用于Android。但我一直无法找到iOS的解决方案。看起来iOS根本没有任何类型的错误属性。有人指点什么?