簡體   English   中英

Xamarin.Forms條目-自定義行為和MVVM

[英]Xamarin.Forms Entry - Custom Behaviors and MVVM

我想為我的Xamarin Forms項目添加一些驗證。 這些是一些非常基本的內容,例如:

  • 最小/最大字符串長度
  • 電郵格式
  • 確認密碼

我在項目中使用MVVM Light,因此,我不在Pages中使用任何代碼。

我正在使用以下代碼,嘗試將Behavior的值綁定到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的值也不會更改。 有什么事嗎

提前致謝。

看起來您已經正確設置了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

輸出示例

讓我知道您是否還有其他麻煩。 干杯!

我也面臨着這個問題,找不到滿意的答案,但是似乎行為中的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更合適,因為您的可綁定屬性是只讀的。

在視圖模型中設置斷點時,您將看到布爾值已更新。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM