我想为我的Xamarin Forms项目添加一些验证。这些是一些非常基本的,如:
我在我的项目中使用MVVM Light,因此,我没有在我的页面中使用代码。
我正在使用下面的代码,尝试将行为的值绑定到我的ViewModel中的属性。
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]))$";
public static readonly BindablePropertyKey IsValidPropertyKey = BindableProperty.CreateReadOnly("IsValid", typeof(bool), typeof(EmailValidatorBehavior), 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;
}
}
View.xaml:
<Entry
Placeholder="E-mail"
Text="{Binding Path=User.email, Mode=TwoWay}"
Keyboard="Email">
<Entry.Behaviors>
<EmailValidatorBehavior x:Name="emailValidator" IsValid="{Binding Path=IsEmailValid, Mode=TwoWay}" />
</Entry.Behaviors>
</Entry>
ViewModel.cs:
private bool _IsEmailValid = false;
public bool IsEmailValid
{
get
{
return _IsEmailValid;
}
set
{
_IsEmailValid = value;
RaisePropertyChanged("IsEmailValid");
}
}
即使电子邮件正确且行为的IsValid属性变为true,IsEmailValid的值也不会更改。可能有什么不对?
提前致谢。
答案 0 :(得分:3)
除了您的xaml本地行为附件之外,您似乎已正确设置了所有内容。您需要更改以下内容:
原始示例
<EmailValidatorBehavior x:Name="emailValidator" IsValid="{Binding Path=IsEmailValid, Mode=TwoWay}" />
更新代码
<Entry Placeholder="testing">
<Entry.Behaviors>
<local:EmailValidatorBehavior></local:EmailValidatorBehavior>
</Entry.Behaviors>
</Entry>
<强>输出强>
我在本例中使用了您的自定义行为,一切正常。左侧显示IsValid = false
,右侧显示IsValid = true
。
如果您对此有任何疑问,请告诉我。干杯!
答案 1 :(得分:1)
我也遇到了这个问题而且我找不到令人满意的答案,但似乎行为中的BindingContext
未设置为页面BindingContext
。
由于我不是这方面的专家,我认为会有更优雅的方式,但是;这似乎有效:
首先,将您的页面命名为以后用作参考:
<ContentPage x:Name="Root" etc, etc>
然后,在您的行为中:将路径和来源设置为页面的绑定上下文:
<Entry Text="{Binding RegistrationEmail}">
<Entry.Behaviors>
<connector:EmailValidatorBehavior
IsValid="{Binding Source={x:Reference Root},
Path=BindingContext.IsRegistrationEmailValid, Mode=OneWayToSource}"/>
</Entry.Behaviors>
</Entry>
顺便说一句,我认为使用Mode=OneWayToSource
更合适,因为您的可绑定属性是只读的。
在viewmodel中设置断点时,您将看到布尔值已更新。