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的主要内容,如果未能解决你的问题,请参考以下文章

csharp Xamarin.Forms条目只有底部边框。

在 Xamarin.Forms 条目视图中使用仅英文键盘

Xamarin.Forms 仅在一个平台 (iOS) 上更改条目的占位符颜色和文本颜色

不应在其焦点上显示软键盘的 Xamarin.Forms 条目

Xamarin Forms WinRT 条目自定义渲染器

条目渲染不在iOS Xamarin Forms中添加下划线