Как назначить сообщение об ошибке хорошей текстовой метке с помощью FluentValidaiton в моем приложении xamarin.forms - PullRequest
0 голосов
/ 09 июля 2020

Пользователь в настоящее время заполняет форму, в которой есть несколько записей. Прямо сейчас у меня есть метка под каждой записью, на которой будет отображаться сообщение об ошибке, если проверка не пройдет.

Моя проблема в том, что прямо сейчас я не могу назначить правильное сообщение об ошибке правильной метке. Потому что, если одна ошибка происходит, а другая нет, я получаю сообщение об отсутствии индекса, что делает разумным.

Возможно ли это? Примечание: это первый раз, когда я использую Fluent Validation, и реализация может быть не очень хорошей. Так что не стесняйтесь предлагать лучшую реализацию

Я создал себе класс Validator, который содержит свойство, к которому я привязываюсь в моем пользовательском интерфейсе. Они будут использоваться для отображения сообщения об ошибке. (Обратите внимание, что они также были определены в BaseViewModel.cs)

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

        public string TasksGroupDateWarning { get; set; }
}

Мои две записи с их меткой, назначенной свойствам

    <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>

My TasksGroupValidator.cs, который проверяет объект TasksGroup.

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();
            }

1 Ответ

1 голос
/ 10 июля 2020

Вы можете использовать Dictionary для хранения сообщений проверки.

Вот фрагмент кода, вы можете адаптировать его к своему коду.

ViewModel:

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>
...
...