如何简化相互依赖的绑定?
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
我有一个条目,当条目为空时,我想给出一个红色轮廓。我正在为我的条目使用 SyncFusion 的 SFTextInputLayout,它有一个 属性 "HasError",一旦它设置为 true,它会自动以红色突出显示我的整个内容。
这是 SFTextInputLayout
<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