Xamarin.Forms 条目 - 自定义行为和 MVVM
Posted
技术标签:
【中文标题】Xamarin.Forms 条目 - 自定义行为和 MVVM【英文标题】:Xamarin.Forms Entry - Custom Behaviors and MVVM 【发布时间】:2017-08-16 05:04:48 【问题描述】:我想为我的 Xamarin Forms 项目添加一些验证。这些是一些非常基本的内容,例如:
最小/最大字符串长度 电子邮件格式 密码确认我在我的项目中使用 MVVM Light,因此,我没有在我的页面中使用代码。
我正在使用下面的代码,尝试将 Behavior 的值绑定到我的 ViewModel 中的属性。
EmailValidatorBehavior.cs:
public class EmailValidatorBehavior : Behavior<Entry>
const string emailRegex = @"^(?("")("".+?(?<!\\)""@)|(([0-9a-z]((\.(?!\.))|[-!#\$%&'\*\+/=\?\^`\\\|~\w])*)(?<=[0-9a-z])@))" +
@"(?(\[)(\[(\d1,3\.)3\d1,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");
IsEmailValid 的值永远不会改变,即使电子邮件是正确的并且行为的 IsValid 属性变为 true。有什么问题?
提前致谢。
【问题讨论】:
你发现了吗? 【参考方案1】:除了 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
。
如果您对此有任何问题,请告诉我。干杯!
【讨论】:
【参考方案2】:我也遇到了这个问题,找不到满意的答案,但似乎行为中的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
更合适,因为您的可绑定属性是只读的。
在视图模型中设置断点时,您会看到布尔值已更新。
【讨论】:
感谢您正确设置 BindingContext!以上是关于Xamarin.Forms 条目 - 自定义行为和 MVVM的主要内容,如果未能解决你的问题,请参考以下文章
Xamarin.Forms 仅在一个平台 (iOS) 上更改条目的占位符颜色和文本颜色