如何同时引用和绑定属性?

时间:2017-11-20 10:11:20

标签: xamarin.forms

这就是我所说的标题。我有一个名为" IsValid" (bool)绑定到一个行为(它被称为Validator),它检查输入是否在范围内(在这种情况下为0 - 10)并为条目的背景着色为红色或透明。这很好。但是,因为我在ViewModel中有相同的逻辑(检查输入是否在范围内)并显示对话框消息(如果不是),我想直接绑定到验证器的IsValid并使用bind fild in我的viewModel(IsBinReferenceValid)abd因此从vm中删除了locig。目前,我的vm IsBinReferenceValid中的属性不会以任何方式更改,表明绑定不起作用。

这是xaml代码:

<userControl:DetailedEntry
            PlaceholderLabel="{x:Static locale:BinPrintLang.BinRef}"
            Text="{Binding BinTextEntry}"
            TextColor="{StaticResource PrimaryColor}"
            BgColor="White"
            BorderColor="{StaticResource DisableColor}"
            VerticalOptions="CenterAndExpand"
            IsLabelVisible="True"
            Label="Bin Reference"
            IsImportant="True"
            IsValid="{Binding Source={x:Reference InputLengthValidator}, Path=IsValid}">
            <userControl:DetailedEntry.EntryBehavior>
                <ui:InputLengthValidator x:Name="InputLengthValidator"
                                         MinValue="0"
                                         MaxValue="10" 
                                         IsValid="{Binding Source=IsBinReferenceValid, Mode=OneWayToSource}"/>
            </userControl:DetailedEntry.EntryBehavior>
        </userControl:DetailedEntry>

我可以同时引用和绑定到某个属性的任何想法,即使是可能的(也就是说,如果问题来自哪里)?

基础验证码:

 public class ValueInRangeValidator : Validator<Entry>
{
    private static BindableProperty MinValueProperty =
        BindableProperty.Create("MinValue", typeof(decimal?), typeof(ValueInRangeValidator));

    public decimal? MinValue
    {
        get { return (decimal?) GetValue(MinValueProperty); }
        set
        {
            SetValue(MinValueProperty, value);
            OnPropertyChanged();
        }
    }

    public static BindableProperty MaxValueProperty =
        BindableProperty.Create("MaxValue", typeof(decimal?), typeof(ValueInRangeValidator));

    public decimal? MaxValue
    {
        get { return (decimal?) GetValue(MaxValueProperty); }
        set
        {
            SetValue(MaxValueProperty, value);
            OnPropertyChanged();
        }
    }


    public  virtual void Bindable_TextChanged(object sender, TextChangedEventArgs e)
    {
        decimal i = 0;
        IsValid = decimal.TryParse(e.NewTextValue, out i);

        IsValid = IsValid && (MinValue == null ? i >= decimal.MinValue : i >= MinValue);
        IsValid = IsValid && (MaxValue == null ? i <= decimal.MaxValue : i <= MaxValue);
    }

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

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

InputLengthValidator代码:

public class InputLengthValidator : ValueInRangeValidator
{

    public override void Bindable_TextChanged(object sender, TextChangedEventArgs e)
    {
        var max = (int) MaxValue;
        var min = (int) MinValue;
        var textLenght = e.NewTextValue.Length;
        IsValid = textLenght >= min && textLenght < max;
    }
}

1 个答案:

答案 0 :(得分:0)

我设法通过订阅名为 IsWarning 的DetailedEntry控件的另一个(自定义)可绑定属性来使验证工作。

<userControl:DetailedEntry
 rid.Row="1"
 Grid.Column="0"
 Label="{x:Static locale:GoodsReceiptLang.NumLabels}"
 Text="{Binding NumberOfLabels, Mode=TwoWay}"
 TextColor="{StaticResource PrimaryColor}"
 Keyboard="Numeric"
 IsImportant="True"
 IsWarning="{Binding ShowWarning}">
 </userControl:DetailedEntry>

我的虚拟机:

private bool CanPrint()
    {
        var errors = new List<string>();

        ShowWarning = false;

        if (SelectedPrinter == null)
            errors.Add(CommonLang.SelectPrinterErrorMsg);

        if (string.IsNullOrEmpty(NumberOfLabels) || !int.TryParse(NumberOfLabels, out int numLabels))
        {
            ShowWarning = true;
            errors.Add(CommonLang.NotValidInput);
        }

        if (errors.Any())
        {
            ShowErrorMessage(string.Join(" ", errors.ToArray()));
            return false;
        }

        return true;
    }