首页 > 解决方案 > Xamarin 使用错误标签形成行为输入验证

问题描述

我正在开发一个使用大量用户输入的项目。我有一个这样的输入屏幕 验证前

但我想使用行为来显示带有这样错误消息的标签 验证后

我已经设法在没有行为的情况下实现了这一点,但它需要大量代码,所以我想使用行为来获得更多干净、健壮的代码。我看过很多更改条目文本或颜色的教程,但正如我上面提到的,我正在尝试使用错误标签。我什至不确定这是否可能。

更新了@ToolmakerSteve 我还没有尝试任何东西,因为我不知道如何使用视图模型和数据绑定与数据触发器来实现这一点。我正在使用另一种方法来制作这个,其中包含很多混乱的代码。我的 xaml 看起来像这样

            <!--Name-->
            <Entry
                Placeholder="{xct:Translate Name}"
                Text="{Binding Name}"
                Style="{StaticResource EntryStyle}"/>
            <!--Name Error-->
            <Label
                Text="{Binding NameError}"
                Style="{StaticResource ErrorLabel}"
                IsVisible="{Binding NameErrorVisibility}"
                />

            <!--Email-->
            <Entry
                Placeholder="{xct:Translate Email}"
                Text="{Binding Email}"
                Style="{StaticResource EntryStyle}"/>
            <!--Email Error-->
            <Label
                Style="{StaticResource ErrorLabel}"
                Text="{Binding EmailError}"
                IsVisible="{Binding EmailErrorVisibility}"
                />

            <!--Password-->
            <Entry
                Placeholder="{xct:Translate Password}"
                Text="{Binding Password}"
                Style="{StaticResource EntryStyle}"/>
            <!--Password Error-->
            <Label
                Style="{StaticResource ErrorLabel}"
                Text="{Binding PasswordError}"
                IsVisible="{Binding PasswordErrorVisibility}"
                />

            <!--Confirmed Password-->
            <Entry
                Placeholder="{xct:Translate ConfirmedPassword}"
                Text="{Binding ConfirmedPass}"
                Style="{StaticResource EntryStyle}"/>
            <!--Confirmed Password Error-->
            <Label
                Style="{StaticResource ErrorLabel}"
                Text="{Binding ConfirmedPassError}"
                IsVisible="{Binding ConfirmedPassErrorVisibility}"
                />

标签: xamarinxamarin.forms

解决方案


邮件也有类似的功能,可以参考以下代码:

  <ContentPage.Resources>
    <ResourceDictionary>

      <Style x:Key="baseStyle"
             TargetType="Label">
        <Setter Property="XAlign" Value="Start" />
        <Setter Property="YAlign" Value="Center" />
        <Setter Property="FontSize" Value="Micro" />
        <Setter Property="FontAttributes" Value="Italic" />
      </Style>
      <local:BooleanToObjectConverter x:Key="boolToStyleEmail"
                                           x:TypeArguments="Style">
        <local:BooleanToObjectConverter.FalseObject>
           <Style TargetType="Label" BasedOn="{StaticResource baseStyle}">
            <Setter Property="TextColor" Value="#F44336" />
            <Setter Property="Text" Value="Enter a valid email" />
          </Style>
        </local:BooleanToObjectConverter.FalseObject>
        
        <local:BooleanToObjectConverter.TrueObject>
          <Style TargetType="Label" BasedOn="{StaticResource baseStyle}">
            <Setter Property="TextColor" Value="#4CAF50" />
            <Setter Property="Text" Value="Your email looks good" />
          </Style>
        </local:BooleanToObjectConverter.TrueObject>

      </local:BooleanToObjectConverter>

    </ResourceDictionary>
  </ContentPage.Resources>
  <StackLayout>
    <Grid>

      <Grid.RowDefinitions>
        <RowDefinition />
        <RowDefinition />

      </Grid.RowDefinitions>

      <Grid.ColumnDefinitions>
        <ColumnDefinition Width="Auto" />
        <ColumnDefinition Width="*" />
        <ColumnDefinition Width="40" />
      </Grid.ColumnDefinitions>

      <Entry Grid.Row="0" Grid.Column="1"
             Placeholder="Email" >
        <Entry.Behaviors>
          <local:EmailValidatorBehavior x:Name="emailValidator"/>
        </Entry.Behaviors>
      </Entry>

      <Label Grid.Row="1" Grid.Column="1" Style="{Binding Source={x:Reference emailValidator}, 
                                Path=IsValid, 
                                Converter={StaticResource boolToStyleEmail}}" />

    </Grid>

  </StackLayout>

的代码BooleanToObjectConverter.cs

class BooleanToObjectConverter<T> : IValueConverter
{
    public T FalseObject { set; get; }

    public T TrueObject { set; get; }

    public object Convert(object value, Type targetType,
                          object parameter, CultureInfo culture)
    {
        return (bool)value ? this.TrueObject : this.FalseObject;
    }

    public object ConvertBack(object value, Type targetType,
                              object parameter, CultureInfo culture)
    {
        return ((T)value).Equals(this.TrueObject);
    }
}

的代码EmailValidatorBehavior.cs

   public class EmailValidatorBehavior : Behavior<Entry>
    {
        const string emailRegex = @"^(?("")("".+?(?<!\\)""@)|(([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]))$";

        // Creating BindableProperties with Limited write access: http://iosapi.xamarin.com/index.aspx?link=M%3AXamarin.Forms.BindableObject.SetValue(Xamarin.Forms.BindablePropertyKey%2CSystem.Object) 

        static readonly BindablePropertyKey IsValidPropertyKey = BindableProperty.CreateReadOnly("IsValid", typeof(bool), typeof(NumberValidatorBehavior), false);

        public static readonly BindableProperty IsValidProperty = IsValidPropertyKey.BindableProperty;

        public bool IsValid
        {
            get { return (bool)base.GetValue(IsValidProperty); }
            private set { base.SetValue(IsValidPropertyKey, value); }
        }

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


        void HandleTextChanged(object sender, TextChangedEventArgs e)
        {
            IsValid = (Regex.IsMatch(e.NewTextValue, emailRegex, RegexOptions.IgnoreCase, TimeSpan.FromMilliseconds(250)));
            ((Entry)sender).TextColor = IsValid ? Color.Default : Color.Red;
        }

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

        }
    }

有关更多详细信息,您可以查看:https ://devblogs.microsoft.com/xamarin/behaviors-in-xamarin-forms/ 。

更新:

我认为没有必要将属性 IsValid 与行为分开并将其放在 ViewModel 中。除了在 ValidatorBehavior 中根据属性设置样式外IsValid ,您还可以IsVisible根据行为中的属性为标签 设置属性IsValid

请参考以下代码:

 <Label Grid.Row="1" Grid.Column="1"   Text="please enter valid email" IsVisible="{Binding Source={x:Reference emailValidator}, 
                                Path=IsValid,Converter={StaticResource invertedBoolToBool}}"  TextColor="Red" />

笔记:

  1. invertedBoolToBool是一个 InverseBoolConverter

InverseBoolConverter.cs

public class InvertedBoolConverter : IValueConverter
{
    public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
    {
        return !((bool)value);
    }

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

2.在页面的 ResourceDictionary 中添加以下代码:

  <local1:InvertedBoolConverter x:Key="invertedBoolToBool" />

上面的文章中也有一个示例,您可以在这里查看:https ://github.com/nishanil/Xamarin.Forms-Samples 。


推荐阅读