行为绑定布尔属性不起作用

时间:2019-05-13 07:35:35

标签: xamarin xamarin.forms

这是我的输入行为:

public class EntryLengthValidatorBehavior : Behavior<Entry>
    {
        public int MaxLength { get; set; }
        public double MaxNumber { get; set; }

        public static readonly BindableProperty IsPercentProperty = BindableProperty.Create(nameof(IsPercent), typeof(bool), typeof(EntryLengthValidatorBehavior), false,defaultBindingMode:BindingMode.TwoWay, propertyChanged: (BindableObject bindable, object old_value, object new_value) =>
        {
            ((EntryLengthValidatorBehavior)bindable).UpdateIsPercent((bool)old_value, (bool)new_value);
        });

        public bool IsPercent
        {
            get
            {
                return (bool)GetValue(IsPercentProperty);
            }
            set
            {
                SetValue(IsPercentProperty, value);
            }
        }

        private void UpdateIsPercent(bool old_value, bool new_value)
        {

        }

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

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

        void OnEntryTextChanged(object sender, TextChangedEventArgs e)
        {
              // my code 
        }
    }

在XAMl内部: 我在条目

中使用了此行为
<local:BorderLessEntry Placeholder="{Binding PlaceholderText,Mode=TwoWay}" TextColor="Black" Style="{StaticResource SmallLabel}" PlaceholderColor="#d6d9db" Grid.Row="0" Grid.Column="0"
                                           HorizontalOptions="FillAndExpand" Margin="20,0,20,0" x:Name="discountEntry" Text="{Binding Discount,Mode=TwoWay}" Keyboard="Numeric">
                     <local:BorderLessEntry.Behaviors>
            <local:EntryLengthValidatorBehavior MaxNumber="999999.99" MaxLength="9" IsPercent="{Binding IsPercent}"/>
            </local:BorderLessEntry.Behaviors>
                </local:BorderLessEntry>

从View Model中,我正在绑定IsPercent值

private void ChangeDiscountType()
        {
            if (DiscountType == 1)
            {
                PlaceholderText = $"{GlobalVariables.currency}0.00";
                IsPercent = false;
            }
            else
            {
                PlaceholderText = $"0%";
                IsPercent = true;
            }
        }

这是我在viewmodel中的IsPecent属性

bool _isPercent;
        public bool IsPercent
        {
            get
            {
                return _isPercent;
            }
            set
            {
                _isPercent = value;
                OnPropertyChanged("IsPercent");
            }
        }

所有属性都可以正常工作,但是我从视图模型中绑定的“ IsPercent”属性值却无法正常工作

这里IsPercent是一个布尔型属性,当我设置Hardcoded值(例如:IsPercent =“ True”)时,它将起作用

如何解决这个问题?

3 个答案:

答案 0 :(得分:0)

对于不想使用Behaviors而是想在代码隐藏中使用的人,可以这样做。

ViewModel

public class ViewModel
{
    public int MaxLength = 9;
    public double MaxNumber = 999999.99;

    private bool _isPercent;
    public bool IsPercent
    {
        get { return _isPercent; }
        set
        {
            if(_isPercent != value)
            {
                _isPercent = value;
                OnPropertyChanged();
            }
        }
    }

    private string _entryText;
    public string EntryText
    {
        get { return _entryText; }
        set
        {
            if (_entryText != value)
            {
                _entryText = value;
                CheckEntryTextFormat(_entryText);
                OnPropertyChanged();
            }
        }
    }

    private void CheckEntryTextFormat(string entryText)
    {
        if (!string.IsNullOrEmpty(entryText))
        {
            if (entryText.All(char.IsDigit) && entryText.Length <= MaxLength && int.Parse(entryText) < MaxNumber)
            {
                IsPercent = true;
            }
            else
            {
                IsPercent = false;
            }
        }
    }
}

Xaml

<Entry Text="{Binding EntryText}"/>
<Button x:Name="DoSomethingWithTheEntryText" IsEnabled="{Binding IsPercent}"/>

现在,如果您在条目中写入内容,则会首先调用"CheckEntryTextformat"

然后该功能检查输入的文本是否仅为数字,不超过9且不超过999999.99。

如果是,则将“ IsPercent”属性设置为true,并由于"OnPropertyChanged()"而动态通知并启用按钮。

答案 1 :(得分:0)

在您的View Model类中添加一个IsPresent属性:

 private bool _isPercent;
  public bool IsPercent
{
    get { return _isPercent; }
    set
    {
        if(_isPercent != value)
        {
            _isPercent = value;
            RaisePropertyChanged("IsPercent");
        }
    }
}

确保为上述属性分配一些值,否则它将每次选择默认值。

您的Xaml看起来像这样:

<local:EntryLengthValidatorBehavior MaxNumber="999999.99" MaxLength="9" IsPercent="{Binding IsPercent}"/>

根据您的行为,您可以使用OnPropertyChanged来监视IsPresent属性中的更改

 protected override void OnPropertyChanged([CallerMemberName] string propertyName = null)
    {
        base.OnPropertyChanged(propertyName);
        if(propertyName= nameof(IsPercent)){}
    }

或者您可以根据需要方便地使用它们。

更新

仔细观察代码后,我意识到您的Behavior中的IsPresent属性不是可绑定的属性,您需要按照以下行为进行操作:

  public static readonly BindableProperty IsPercentProperty =
      BindableProperty.Create(nameof(IsPercent), typeof(bool), typeof(EntryLengthValidatorBehavior), false);
    private bool _isPercent;
    public bool IsPercent
    {
        get { return _isPercent; }
        set
        {
            if (_isPercent != value)
            {
                _isPercent = value;
                OnPropertyChanged(nameof(IsPercent));
            }
        }
    }

答案 2 :(得分:0)

您的UpdateIsPercent未触发,因为您必须指出该行为的绑定上下文。然后将其可绑定属性绑定到您的视图模型的正确属性:

<local:BorderLessEntry.Behaviors>
    <local:EntryLengthValidatorBehavior MaxNumber="999999.99" MaxLength="9" IsPercent="{Binding BindingContext.IsPercent, Source={x:Reference discountEntry}}"/>
</local:BorderLessEntry.Behaviors>

此外,我还建议您利用附加属性来做到这一点: https://docs.microsoft.com/en-us/xamarin/xamarin-forms/app-fundamentals/behaviors/creating#consuming-a-xamarinforms-behavior-with-a-style