繁体   English   中英

如何在我的 xamarin.forms 应用程序中使用 FluentValidaiton 将错误消息分配给好文本 label

[英]How to assign an error message to the good text label with FluentValidaiton in my xamarin.forms app

用户当前正在填写具有多个条目的表单。 现在我在每个条目下都有一个 label 如果验证没有通过,它将显示错误消息。

我的问题是,现在,我无法将正确的错误消息分配给正确的 label。 因为如果发生一个错误而另一个没有发生,我会收到一个错误,即索引不存在,这很有意义。

可能吗? 注意:这是我第一次使用 Fluent Validation,实施可能不太好。 因此,请随时提出更好的实施方案

我为自己创建了一个验证器 class,其中包含我在 UI 中绑定的属性。 这些将用于显示错误消息。 (注意它们也在 BaseViewModel.cs 中定义)

    public class Validator
    {
        public string TasksGroupDescriptionWarning { get; set; }

        public string TasksGroupDateWarning { get; set; }
}

我的两个条目与他们的 Label 分配给属性

    <StackLayout >
        <Label Text="Date de calcul:" FontAttributes="Bold" FontFamily="ROBOTO" TextColor="#000000"></Label>
        <DatePicker   Date="{Binding TasksGroupDate}" FontFamily="ROBOTO" Format="yyyy-MM-dd" ></DatePicker>
        <Label Text="{Binding TasksGroupDateWarning}" TextColor="#FF0000" FontAttributes="Bold"></Label>

    </StackLayout>
    <StackLayout >
        <Label Text="Description de la journée" FontAttributes="Bold" FontFamily="ROBOTO" TextColor="#000000"></Label>
        <Entry x:Name="TasksGroupDescription" Text="{Binding TasksGroupDescription}"/>
        <Label Text="{Binding TasksGroupDescriptionWarning}" TextColor="#FF0000" FontAttributes="Bold"></Label>

    </StackLayout>

我的 TasksGroupValidator.cs 用于验证 TasksGroup object。

public class TasksGroupValidator : AbstractValidator<TasksGroup>
{

    public TasksGroupValidator()
    {
        RuleFor(p => p.TasksGroupDescription).NotEmpty().WithMessage("* Veuillez entrer une description.");

        RuleFor(p => p.TasksGroupDate).Must(BeValidDate).WithMessage("* Vous ne pouvez pas entrer une date supérieure à celle d'aujourd'hui.");
    }

    protected bool BeValidDate(DateTime date)
    {
        DateTime currentDate = DateTime.Now;

        if (date > currentDate)
        {
            return false;
        }
        return true;
    }
}

这是我保存表单并验证的地方,如果我同时有两个错误,它将起作用,但如果我只有两个错误之一,我将收到第二个索引错误,因为它不存在

  async Task SaveNewTask()
        {
            // in my code i created a TasksGroup object
            TasksGroupValidator tasksGroupValidator = new TasksGroupValidator();
            
           ValidationResult results = tasksGroupValidator.Validate(tasksGroup);

             if (results.IsValid == false)
            {
        //assign to first label
                TasksGroupDescriptionWarning = results.Errors[0].ErrorMessage;
                validator.TasksGroupDescriptionWarning = TasksGroupDescriptionWarning;
              //assign to second label
                TasksGroupDateWarning = results.Errors[1].ErrorMessage;
                validator.TasksGroupDateWarning = TasksGroupDateWarning;
            }
            //else save to database
         }

编辑以在评论中获得答案

 public bool Validate(TasksGroup tasksGroup)
        {
            ValidationResult results = validator.Validate(tasksGroup);
            if (!results.IsValid)
            {
                foreach (var e in results.Errors)
                {
                    ErrorMessages[e.PropertyName] = e.ErrorMessage;
                }

            }

            NotifyPropertyChanged(nameof(ErrorMessages));
            return results.IsValid;

        }

 
        async Task SaveNewTask()
        {

            
            IsBusy = true;
            await Task.Delay(4000);


            IsBusy = false;

            TasksGroup tasksGroup = new TasksGroup();
            Tasks tasks = new Tasks();

            tasksGroup.TasksGroupDescription = TasksGroupDescription;
            tasksGroup.TasksGroupDate = TasksGroupDate;
            tasks.TaskDuration = TaskDuration;
            tasks.TaskDBA = TaskDBA;
            tasks.TaskDescription = TaskDescription;

            tasksGroup.Taches = new List<Tasks>() { tasks };


            if(Validate(tasksGroup))
            {
                await App.Database.SaveTasksGroupAsync(tasksGroup);
 

                await Application.Current.MainPage.DisplayAlert("Save", "La tâche a été enregistrée", "OK");
                await Application.Current.MainPage.Navigation.PopAsync();
                NotifyPropertyChanged();
            }

您可以使用Dictionary来存储验证消息。

这是一个代码片段,您可以将其调整为您的代码。

视图模型:

public class TaskGroupViewModel : INotifyPropertyChanged
{
    public TaskGroup TaskGroup { get; set; }
    public IDictionary<string, string> ErrorMessages { get; set; }
    public ICommand ValidateCommand { get; }

    private readonly AbstractValidator<TaskGroup> _validator;

    public TaskGroupViewModel()
    {
        TaskGroup = new TaskGroup();
        ErrorMessages = new Dictionary<string, string>();
        ValidateCommand = new Command(() => Validate());

        _validator = new InlineValidator<TaskGroup>();
        _validator.RuleFor(x => x.TasksGroupDate)
            .Must(x => x > DateTime.Now)
            .WithMessage("* Vous ne pouvez pas entrer une date supérieure à celle d'aujourd'hui.");

        _validator.RuleFor(x => x.TasksGroupDescription)
            .NotEmpty()
            .WithMessage("* Veuillez entrer une description.");
    }

    public bool Validate()
    {
        ErrorMessages.Clear();

        var result = _validator.Validate(TaskGroup);
        if (!result.IsValid)
        {
            foreach (var e in result.Errors)
            {
                ErrorMessages[e.PropertyName] = e.ErrorMessage;
            }
        }

        OnPropertyChanged(nameof(ErrorMessages));

        return result.IsValid;
    }

    public event PropertyChangedEventHandler PropertyChanged;

    [NotifyPropertyChangedInvocator]
    protected virtual void OnPropertyChanged([CallerMemberName] string propertyName = null)
    {
        PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
    }
}

XAML:

....
<StackLayout>
    <StackLayout >
        <Label Text="Date de calcul:" FontAttributes="Bold" FontFamily="ROBOTO" TextColor="#000000"></Label>
        <DatePicker   Date="{Binding TaskGroup.TasksGroupDate}" FontFamily="ROBOTO" Format="yyyy-MM-dd" ></DatePicker>
        <Label Text="{Binding ErrorMessages[TasksGroupDate]}" TextColor="#FF0000" FontAttributes="Bold"></Label>

    </StackLayout>
    <StackLayout >
        <Label Text="Description de la journée" FontAttributes="Bold" FontFamily="ROBOTO" TextColor="#000000"></Label>
        <Entry x:Name="TasksGroupDescription" Text="{Binding TaskGroup.TasksGroupDescription}"/>
        <Label Text="{Binding ErrorMessages[TasksGroupDescription]}" TextColor="#FF0000" FontAttributes="Bold"></Label>
    </StackLayout>

    <Button Text="Validate" Command="{Binding ValidateCommand, Mode=OneTime}"/>
</StackLayout>
...

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM