我正在尝试实现验证控制。
我有一个页面,其中有一个条目和一个ok 按钮。
该条目是电子邮件输入,我实施了行为,以向用户显示他的输入是否良好。我想将按钮的 IsEnabled 属性绑定到行为的 IsValid 属性。
以下是行为代码:
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 BindableProperty IsValidProperty = BindableProperty.Create("IsValid", typeof(bool), typeof(EmailValidatorBehavior), false);
public bool IsValid
{
get { return (bool)base.GetValue(IsValidProperty); }
private set { base.SetValue(IsValidProperty, value); }
}
protected override void OnAttachedTo(Entry entry)
{
entry.TextChanged += HandleTextChanged;
base.OnAttachedTo(entry);
}
void HandleTextChanged(object sender, TextChangedEventArgs e)
{
bool IsValid = false;
IsValid = (Regex.IsMatch(e.NewTextValue, emailRegex, RegexOptions.IgnoreCase, TimeSpan.FromMilliseconds(250)));
((Entry)sender).TextColor = IsValid ? Color.Default : Color.Red;
}
protected override void OnDetachingFrom(Entry entry)
{
entry.TextChanged -= HandleTextChanged;
base.OnDetachingFrom(entry);
}
}
在页面中,我有这样的行为。 只有当电子邮件验证正则表达式时,颜色变化才会恢复正常
_emailEntry.Behaviors.Add(new EmailValidatorBehavior());
另外,我的页面有一个 bindingContext ,它是一个视图模型。据我所知,我将在这里做我的逻辑绑定。我看到我必须在IsValidProperty上监听属性更改事件,但我无法解决如何实现它。即使我在xamarin的网站上阅读了很多文档,特别是在行为和创建可绑定属性的情况下,我仍然不清楚绑定和 bindableProperty 。我已经开始了:
在页面中:
var behavior = new EmailValidatorBehavior();
//Binding context is LandingViewModel
behavior.SetBinding(EmailValidatorBehavior.IsValidProperty, "IsValid");
_okButton.SetBinding(MR.Gestures.Button.IsEnabledProperty, "IsEnabled");
_emailEntry.Behaviors.Add(behavior);
以下是视图模型:
public class LandingViewModel : BaseViewModel
{
private bool _isEnabled;
private bool _isValid;
public bool IsEnabled
{
get { return _isEnabled; }
set
{
if (_isEnabled == value) return;
_isEnabled = value;
OnPropertyChanged("IsEnabled");
}
}
public bool IsValid
{
get { return _isValid; }
set
{
Debug.WriteLine(_isValid);
if (_isValid == value) return;
_isValid = value;
IsEnabled = _isValid;
Debug.WriteLine(_isValid);
OnPropertyChanged("IsValid");
}
}
我不高兴,我看到我显然遗失了什么,却看不出来......
非常感谢你。
答案 0 :(得分:3)
查看您添加的Debug.WriteLine()
,我猜测绑定未设置IsValid
属性。
这是因为您没有设置DefaultBindingMode
的{{1}},或者因为您没有设置BindableProperty
本身的BindingMode
。因此绑定默认为Binding
,这意味着在更改视图模型时会修改您的行为OneWay
,而不是相反。
以这种方式创建IsValid
:
BindableProperty
这应该有用。
如果我可以的话还有一些补充说明:
您可以将public static BindableProperty IsValidProperty =
BindableProperty.Create("IsValid", typeof(bool), typeof(EmailValidatorBehavior),
false, BindingMode.TwoWay);
Entry
属性直接绑定到行为IsEnabled
属性。
IsValid
如果您这样做,行为将成为绑定的来源,您不必创建var behavior = new EmailValidatorBehavior();
_okButton.SetBinding(MR.Gestures.Button.IsEnabledProperty, new Binding("IsEnabled", source: behavior));
_emailEntry.Behaviors.Add(behavior);
,您只需实施BindableProperty
。
INotifyPropertyChanged
个实例如果您在样式中共享此行为,则将重用相同的实例,并且它将无法按预期工作。
答案 1 :(得分:1)
您的视图模型中没有IsEnabled
属性,因此行OnPropertyChanged("IsEnabled");
根本不会做任何事情。我认为您需要做的是将SetIsEnabledButton
属性的名称更改为IsEnabled
,并将行_isEnabled = _isValid;
更改为IsEnabled = _isValid;
。这样设置IsValid
时,它会将控件转移到IsEnabled
setter,然后会自动引发属性更改通知。
如果你仍然无法让它工作,请回到这里。
答案 2 :(得分:0)
我已经发现它能够正常工作,而且由于@Stephane Delcroix的帖子,我不需要任何视图模型。
我仍然对@Stephane Delcroix建议之后的行为拥有可绑定属性。
public static BindableProperty IsValidProperty = BindableProperty.Create("IsValid", typeof(bool), typeof(EmailValidatorBehavior), false, BindingMode.TwoWay);
要在isValid属性上绑定我的按钮,我写道:
_okButton.SetBinding(IsEnabledProperty,
new Binding(EmailValidatorBehavior.IsValidProperty.PropertyName));
&#34;参考PropertyName而不是&#34; Value&#34;这是一个很好的做法。喜欢&#34; IsValid&#34;,以这种方式避免字符串中的任何拼写错误,并且编译器和完成都避免错误&#34;。
我在行为上设置了我的按钮的bindingContext:
_okButton.BindingContext = _emailBehavior;