amwx / FluentAvalonia

Control library focused on fluent design and bringing more WinUI controls into Avalonia
MIT License
973 stars 92 forks source link

Did CalendarDatePicker support INotifyDataErrorInfo #139

Closed alex6dj closed 1 year ago

alex6dj commented 2 years ago

Describe the bug According to this PR https://github.com/AvaloniaUI/Avalonia/pull/7308 validation with Avalonia is handled correctly when using CalendarDatePicker.SelectedDate property (didn't tested). Now Im using the last version of FluentAvalonia but I cant make it to work, not sure if it is an Avalonia or this library bug. The validation is running correctly against a TextBox but not against CalendarDatePicker, it didnt show any visual indication. Maybe Im missing something. If I set the same validation against a property binding to a textbox I can see the validation error. Maybe you can provide a workaround.

Screenshots Failed validation state. In the Textbox the error appears but the CalendarDatePicker dont show any date validation error. Captura de pantalla (151)

Desktop/Platform (please complete the following information):

Additional context Code sample:

using System;
using DataModel;
using ReactiveUI;
using ReactiveUI.Fody.Helpers;
using ReactiveUI.Validation.Extensions;

namespace ViewModels.Modules.Competitions
{
    public class CompetitionProxy : ValidatableViewModelBase
    {
        public CompetitionProxy(Competition competition)
        {
            Competition = competition ?? throw new ArgumentNullException(nameof(competition));

            InitializeProperties(competition);

            InitializeValidations();

            UpdateSkaterOnValueChange();
        }

        public Competition Competition { get; }

        [Reactive] public DateTime StartDate { get; set; }

        [Reactive] public DateTime EndDate { get; set; }

        private void InitializeProperties(Competition competition)
        {            
            StartDate = competition.StartDate;
            EndDate = competition.EndDate;
        }

        private void InitializeValidations()
        {
            // Start date
            // End date
            var checkDateRangeObservable = this.WhenAnyValue(
                viewModel => viewModel.StartDate,
                viewModel => viewModel.EndDate,
                (startDate, endDate) => startDate < endDate);

            this.ValidationRule(
                viewModel => viewModel.EndDate,
                checkDateRangeObservable,
                "Competition end date must after start date"); // Date validation
        }
    }
}
<UserControl xmlns="https://github.com/avaloniaui"
             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
             xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
             xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
             mc:Ignorable="d" d:DesignWidth="800" d:DesignHeight="450"
             x:Class="PatiTournApp.Modules.Competitions.CompetitionProxyEditorView">
    <Grid RowDefinitions="* * * * * * * *">
        <TextBlock Grid.Row="4" Text="Start date:" />
        <CalendarDatePicker Grid.Row="5"  SelectedDate="{Binding StartDate}" />

        <TextBlock Grid.Row="6" Text="End date:" />
        <CalendarDatePicker Grid.Row="7" SelectedDate="{Binding EndDate}" />
    </Grid>
</UserControl>
amwx commented 2 years ago

It's a styling issue here... https://github.com/amwx/FluentAvalonia/blob/172ab14f0c4ddb8b4025a9699e3ad35d174bb08a/FluentAvalonia/Styling/BasicControls/CalendarDatePickerStyles.axaml#L25-L122

I didn't add a separate DataValidationErrors item as the root of the control template, instead template binded it to the TextBox. Theoretically that should work (and should be the way to do it) but for some reason it doesn't

EDIT: After looking into this more, it appears to be an issue with the actual control. I was able to repro with a very basic INotifyDataErrorInfo test with both my theme and the stock Fluent theme - and also checked the template for what I previously said and could not get binding to trigger the error info. I'd suggest opening an issue on Avalonia about this. Interestingly errors do show up if you set the error in Xaml as an attached property, but seem to fail if binding.