如何简化相互依赖的绑定?

How to simplify bindings that depend on each other?

我有一个条目,当条目为空时,我想给出一个红色轮廓。我正在为我的条目使用 SyncFusion 的 SFTextInputLayout,它有一个 属性 "HasError",一旦它设置为 true,它会自动以红色突出显示我的整个内容。

这是 SFTextInputLayout

的以下 XAML 代码
 <inputLayout:SfTextInputLayout Grid.Column="0" Hint="Phone Number" ContainerType="{StaticResource RepairOrderContainerType}" HasError="{Binding IsPhoneNumberError}" FocusedColor="{StaticResource AccentColor}" VerticalOptions="Center" HorizontalOptions="Start">
       <Entry Keyboard="Telephone" Style="{StaticResource TextInputStyle}" Text="{Binding PhoneNumber}"/>
 </inputLayout:SfTextInputLayout>

如您所见,我有两个绑定处理条目的文本,另一个绑定用于检查它是否有错误。虽然这个解决方案有效,但随着我的输入字段数量的增加,它很快就会变得多余。对于我拥有的每个输入字段,我需要另一个布尔值来覆盖其错误 属性,如下所示。

  private string _phoneNumber;
    public string PhoneNumber
    {
        get => _phoneNumber;
        set
        {
            IsPhoneNumberError = string.IsNullOrWhiteSpace(value) ? true : false;
            this.RaiseAndSetIfChanged(ref _phoneNumber, _phoneNumber);
        }
    }

    private bool _isPhoneNumberError = false;
    public bool IsPhoneNumberError
    {
        get => _isPhoneNumberError;
        set
        {
            this.RaiseAndSetIfChanged(ref _isPhoneNumberError, value);
        }
    }

我想知道是否有任何方法可以简化这段代码。提前致谢!

许多实现此目的的方法之一是创建具有行为的自定义控件。

创建自定义控件:

public class MySfTextInputLayout : SfTextInputLayout
{

    public MySfTextInputLayout ()
    {
        Behaviors.Add(new ShowErrorBehavior());
    }
    public bool HasErrors
    {
        get { return (bool)GetValue(HasErrorsProperty); }
        set { SetValue(HasErrorsProperty, value); }
    }
    public static readonly BindableProperty HasErrorsProperty =
        BindableProperty.Create(nameof(HasErrors), typeof(bool), typeof(MySfTextInputLayout ), false);

}

和行为:

public class ShowErrorBehavior : Behavior<MySfTextInputLayout>
{
    protected override void OnAttachedTo(MySfTextInputLayout entry)
    {
        entry.TextChanged += OnEntryTextChanged;
        base.OnAttachedTo(entry);
    }
    protected override void OnDetachingFrom(MySfTextInputLayout entry)
    {
        entry.TextChanged -= OnEntryTextChanged;
        base.OnDetachingFrom(entry);
    }

    void OnEntryTextChanged(object sender, TextChangedEventArgs args)
    {
        ((MySfTextInputLayout)sender).HasErrors = string.IsNullOrWhiteSpace(args.NewTextValue);
    }
}

该行为将为您决定文本的有效性,因此您不必为此绑定到另一个 属性。 另请查看验证 API,您可能希望为一个条目添加多个规则:

https://devblogs.microsoft.com/xamarin/validation-xamarin-forms-enterprise-apps/

您可以通过将输入文本绑定到 HasError 属性 并使用转换器来实现添加多个输入字段时处理错误的要求,如下面的代码片段所示。

代码片段[Xaml]:

<StackLayout > 
    <inputLayout:SfTextInputLayout 
       Grid.Column="0" 
       HasError="{Binding Text,Source={x:Reference entry1}, Converter={StaticResource Converter}}" 
       Hint="Phone Number" 
       HorizontalOptions="Start" 
       VerticalOptions="Center"> 
       <Entry x:Name="entry1" Keyboard="Telephone" Text="{Binding PhoneNumber}" /> 
    </inputLayout:SfTextInputLayout> 

    <inputLayout:SfTextInputLayout 
       Grid.Column="0" 
       HasError="{Binding Text,Source={x:Reference entry2}, Converter={StaticResource Converter}}" 
       Hint="Address" 
       HorizontalOptions="Start" 
       VerticalOptions="Center"> 
       <Entry x:Name="entry2" Text="{Binding Address}" /> 
    </inputLayout:SfTextInputLayout> 
</StackLayout> 

代码片段 [C#]:

public class Converter : IValueConverter 
{ 
    public object Convert(object value, Type targetType, object parameter, CultureInfo culture) 
    { 
        if (value != null) 
        { 
            return string.IsNullOrEmpty(value.ToString()) ? true : false; 
        } 

        return value; 
    } 

    public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture) 
    { 
        return value; 
    } 
} 

示例:https://www.syncfusion.com/downloads/support/directtrac/general/ze/TextInputLayout-1703941642.zip