2017-05-11 69 views
2

我有檢查的電子郵件地址行爲不觸發OnPropertyChanged

using System; 
using System.Collections.Generic; 
using System.Text; 
using System.Text.RegularExpressions; 
using Xamarin.Forms; 

namespace AllTheSame.Behaviors.Validator 
{ 
    public class EmailValidatorBehavior : Behavior<Entry> 
    { 
     private static readonly BindablePropertyKey IsValidPropertyKey = BindableProperty.CreateReadOnly("IsValid", typeof(bool), typeof(EmailValidatorBehavior), default(bool), BindingMode.TwoWay); 

     public static readonly BindableProperty IsValidProperty = IsValidPropertyKey.BindableProperty; 

     public bool IsValid 
     { 
      get => (bool) GetValue(IsValidProperty); 
      private set => SetValue(IsValidPropertyKey, value); 
     } 

     protected override void OnAttachedTo(Entry bindable) 
     { 
      base.OnAttachedTo(bindable); 
      bindable.TextChanged += HandleTextChanged; 
     } 

     private void HandleTextChanged(object sender, TextChangedEventArgs e) 
     { 
      try 
      { 
       IsValid = Regex.IsMatch(e.NewTextValue, "^(?(\")(\".+?(?<!\\\\)\"@)|(([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]))$"); 
      } 
      catch 
      { 
       IsValid = false; 
      } 
      finally 
      { 
       ((Entry) sender).TextColor = IsValid ? Color.Default : Color.Red; 
      } 
     } 

     protected override void OnDetachingFrom(Entry bindable) 
     { 
      base.OnDetachingFrom(bindable); 
      bindable.TextChanged -= HandleTextChanged; 
     } 
    } 
} 

定製行爲,我用它像這樣在我的XAML頁面

... 
<ContentPage.BindingContext> 
    <viewModels:RegisterViewModel /> 
</ContentPage.BindingContext> 
... 
<Entry Placeholder="Email" Text="{Binding Email}"> 
    <Entry.Behaviors> 
     <validator:EmailValidatorBehavior x:Name="EmailValidatorBehavior" IsValid="{Binding IsEmailValid}"/> 
    </Entry.Behaviors> 
</Entry> 

我的頁面是綁定到我的RegisterViewModel,和我在其中獲得了一個「IsEmailValid」屬性。

public bool IsEmailValid 
{ 
    get => _isEmailValid; 
    set 
    { 
     _isEmailValid = value; 
     OnPropertyChanged(); 
     SignUpCommand.ChangeCanExecute(); 
    } 
} 

private bool _isEmailValid; 

的問題是,當我改變條目的文本,執行的行爲「HandleTextChanged」的方法,但我的財產「IsEmailValid」在我的「RegisterViewModel」的值不會改變。我可能在這裏做錯了事,但我無法弄清楚。我嘗試在我的行爲中使用BindableProperty.Create,但沒有任何更改。

你能幫助我嗎?

回答

0

難道你需要一個INotifyPropertyChanged? 這裏有一個例子:

public class Data : INotifyPropertyChanged 
{ 
// boiler-plate 
public event PropertyChangedEventHandler PropertyChanged; 
protected virtual void OnPropertyChanged(string propertyName) 
{ 
    PropertyChangedEventHandler handler = PropertyChanged; 
    if (handler != null) handler(this, new PropertyChangedEventArgs(propertyName)); 
} 
protected bool SetField<T>(ref T field, T value, string propertyName) 
{ 
    if (EqualityComparer<T>.Default.Equals(field, value)) return false; 
    field = value; 
    OnPropertyChanged(propertyName); 
    return true; 
} 

// props 
private string name; 
public string Name 
{ 
    get { return name; } 
    set { SetField(ref name, value, "Name"); } 
} 

}

+0

一點也不添加的回調。我將行爲綁定到我的視圖模型中的屬性「IsEmailValid」。但是價值永遠不會被行爲得到或設置。我需要該行爲才能夠更改視圖模型中的屬性 – JordaanMe

0

我會先嚐試設置IsValid的結合雙向的。

<validator:EmailValidatorBehavior ... IsValid="{Binding IsEmailValid, Mode=TwoWay}"/> 

如果不工作,我會嘗試的綁定屬性

public static readonly BindableProperty IsValidProperty = 
BindableProperty.CreateReadOnly("IsValid", typeof(bool), typeof(EmailValidatorBehavior), null, 
propertyChanged: OnIsValidChanged); 

static void OnIsValidChanged (BindableObject bindable, object oldValue, object newValue) 
{ 
    // Property changed implementation goes here 
}