2017-03-23 24 views
2

私のXamarinフォームプロジェクトにいくつかのバリデーションを追加したいと思います。これらは、のようないくつかの非常に基本的なものです:Xamarin.Forms Entry - カスタムビヘイビアとMVVM

  • 最小/最大文字列の長さ
  • メール形式
  • 私は私のプロジェクトにし、そのためMVVMライトを使用してい

パスワード確認、I私のページでコードを使用していません。

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の値は決して変更されません。何が間違っていますか?

ありがとうございます。

+0

これを把握しましたか? – AhmedW

答えて

2

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が表示されます。

Example output

あなたはこれで任意のより多くの悩みを持っているなら、私に教えてください。乾杯!

0

私もこの問題に直面していました。私は満足のいく答えを見つけることができませんでしたが、動作の中の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

viewmodelにブレークポイントを設定すると、ブール値が更新されていることがわかります。

関連する問題