我有检查电子邮件地址的自定义行为
using System;
using System.Collections.Generic;
using System.Text;
using System.Text.RegularExpressions;
using Xamarin.Forms;
namespace AllTheSame.Behaviors.Validator
{
public class EmailValidatorBehavior : Behavior<Entry>
{
private static readonly BindablePropertyKey IsValidPropertyKey = BindableProperty.CreateReadOnly("IsValid", typeof(bool), typeof(EmailValidatorBehavior), default(bool), BindingMode.TwoWay);
public static readonly BindableProperty IsValidProperty = IsValidPropertyKey.BindableProperty;
public bool IsValid
{
get => (bool) GetValue(IsValidProperty);
private set => SetValue(IsValidPropertyKey, value);
}
protected override void OnAttachedTo(Entry bindable)
{
base.OnAttachedTo(bindable);
bindable.TextChanged += HandleTextChanged;
}
private void HandleTextChanged(object sender, TextChangedEventArgs e)
{
try
{
IsValid = Regex.IsMatch(e.NewTextValue, "^(?(\")(\".+?(?<!\\\\)\"@)|(([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]))$");
}
catch
{
IsValid = false;
}
finally
{
((Entry) sender).TextColor = IsValid ? Color.Default : Color.Red;
}
}
protected override void OnDetachingFrom(Entry bindable)
{
base.OnDetachingFrom(bindable);
bindable.TextChanged -= HandleTextChanged;
}
}
}
我在我的XAML页面中使用了这个
...
<ContentPage.BindingContext>
<viewModels:RegisterViewModel />
</ContentPage.BindingContext>
...
<Entry Placeholder="Email" Text="{Binding Email}">
<Entry.Behaviors>
<validator:EmailValidatorBehavior x:Name="EmailValidatorBehavior" IsValid="{Binding IsEmailValid}"/>
</Entry.Behaviors>
</Entry>
我的页面绑定到我的RegisterViewModel,我的中有一个属性“IsEmailValid”。
public bool IsEmailValid
{
get => _isEmailValid;
set
{
_isEmailValid = value;
OnPropertyChanged();
SignUpCommand.ChangeCanExecute();
}
}
private bool _isEmailValid;
问题是,当我更改条目的文本时,行为中的“HandleTextChanged”方法被执行,但我的“RegisterViewModel”中的属性“IsEmailValid”的值不会更改。我可能在这里做错了但我无法弄明白。我尝试在我的行为中使用BindableProperty.Create,但没有任何改变。
你能帮我吗?
答案 0 :(得分:0)
您是否需要INotifyPropertyChanged? 这是一个例子:
public class Data : INotifyPropertyChanged
{
// boiler-plate
public event PropertyChangedEventHandler PropertyChanged;
protected virtual void OnPropertyChanged(string propertyName)
{
PropertyChangedEventHandler handler = PropertyChanged;
if (handler != null) handler(this, new PropertyChangedEventArgs(propertyName));
}
protected bool SetField<T>(ref T field, T value, string propertyName)
{
if (EqualityComparer<T>.Default.Equals(field, value)) return false;
field = value;
OnPropertyChanged(propertyName);
return true;
}
// props
private string name;
public string Name
{
get { return name; }
set { SetField(ref name, value, "Name"); }
}
}
答案 1 :(得分:0)
我首先尝试将IsValid绑定设置为双向。
<validator:EmailValidatorBehavior ... IsValid="{Binding IsEmailValid, Mode=TwoWay}"/>
如果这不起作用,我会尝试在可绑定属性上添加回调
public static readonly BindableProperty IsValidProperty =
BindableProperty.CreateReadOnly("IsValid", typeof(bool), typeof(EmailValidatorBehavior), null,
propertyChanged: OnIsValidChanged);
static void OnIsValidChanged (BindableObject bindable, object oldValue, object newValue)
{
// Property changed implementation goes here
}