wpfvalidationviewviewmodelcatel

Catel validation errors not shown in view


I have a problem with Catel in showing the results of field validations (done in a view model or a model) in a view: with an error in a field, the corresponding textbox shall be marked like with a red frame. But for some reason I do not get this working.

This is a very simplified test scenario with a viewmodel having 2 integer fields, and validation rules requiring both having values < 100:

    public class MainViewModel : ViewModelBase
    {
        public MainViewModel() : base()
        { }

        protected override async Task InitializeAsync()
        {
            await base.InitializeAsync();
        }

        protected override async Task CloseAsync()
        {
            await base.CloseAsync();
        }

        public override string Title { get { return "Test"; } }


        public int Value1
        {
            get { return GetValue<int>(Value1Property); }
            set { SetValue(Value1Property, value); }
        }
        public static readonly PropertyData Value1Property = RegisterProperty(nameof(Value1), typeof(int), 42 );

        public int Value2
        {
            get { return GetValue<int>(Value2Property); }
            set { SetValue(Value2Property, value); }
        }
        public static readonly PropertyData Value2Property = RegisterProperty(nameof(Value2), typeof(int), 99);


        protected override void ValidateFields(List<IFieldValidationResult> validationResults)
        {
            if (Value1 >= 100)
            {
                validationResults.Add(FieldValidationResult.CreateError(Value1Property, "Value1 must be < 100" ));
            }

            if (Value2 >= 100)
            {
                validationResults.Add(FieldValidationResult.CreateError(Value1Property, "Value2 must be < 100"));
            }
        }

        protected override void ValidateBusinessRules(List<IBusinessRuleValidationResult> validationResults)
        {  }
    }
}

Please note: in my real project, the fields and validation would be in a model, but for test reasons I have stripped this down to just a view and a view model.

And this simple view has the viewmodel as the datacontext:

<catel:Window x:Class="WPF_Catel_Validation.Views.MainWindow"
              xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
              xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
              xmlns:i="http://schemas.microsoft.com/expression/2010/interactivity"
              xmlns:catel="http://schemas.catelproject.com">

    <StackPanel Orientation="Vertical" HorizontalAlignment="Left">
        <TextBox Text="{Binding Value1, NotifyOnValidationError=True, ValidatesOnDataErrors=True}" Width="100" />
        <TextBox Text="{Binding Value2, NotifyOnValidationError=True, ValidatesOnDataErrors=True}" Width="100" />
    </StackPanel>    
</catel:Window>

The connection between view and viewmodel works. The view also shows an error when a non-numeric text is entered in a textbox. The viewmodel with the method ValidateFields() also identifies any errors, but the view does not show these validation errors with a red frame around the textbox.

I have done my tests with Catel 5.8.0 and .NET 4.7.2. I wonder a little how the Catel-class ViewModelBase can implement INotifyDataErrorInfo, but the event ErrorsChanged is not visible in that class. But in general I have no clue if something is wrong with my viewmodel, or my view, or with Catel, or anything else? I also did not find any up-to-date documentation on Catel. Any suggestions are highly appreciated - thanks!


Solution

  • Probably you need to set DeferValidationUntilFirstSave to false if you want to show them immediately.