fluent validation wpf show error on save code example

Example 1: how to implement FluentValidation in wpf

using System;
using System.ComponentModel;
using System.Linq;
using WpfFluentValidationExample.Lib;

namespace WpfFluentValidationExample.ViewModels
{
    public class UserViewModel : INotifyPropertyChanged, IDataErrorInfo
    {
        private readonly UserValidator _userValidator;
        private string _zip;
        private string _email;
        private string _name;

        public UserViewModel()
        {
            _userValidator = new UserValidator();
        }

        public string Name
        {
            get { return _name; }
            set
            {
                _name = value;
                OnPropertyChanged("Name");
            }
        }

        public string Email
        {
            get { return _email; }
            set
            {
                _email = value;
                OnPropertyChanged("Email");
            }
        }

        public string Zip
        {
            get { return _zip; }
            set
            {
                _zip = value;
                OnPropertyChanged("Zip");
            }
        }

        public string this[string columnName]
        {
            get
            {
                var firstOrDefault = _userValidator.Validate(this).Errors.FirstOrDefault(lol => lol.PropertyName == columnName);
                if (firstOrDefault != null)
                    return _userValidator != null ? firstOrDefault.ErrorMessage : "";
                return "";
            }
        }

        public string Error
        {
            get
            {
                if (_userValidator != null)
                {
                    var results = _userValidator.Validate(this);
                    if (results != null && results.Errors.Any())
                    {
                        var errors = string.Join(Environment.NewLine, results.Errors.Select(x => x.ErrorMessage).ToArray());
                        return errors;
                    }
                }
                return string.Empty;
            }
        }

        public event PropertyChangedEventHandler PropertyChanged;

        protected virtual void OnPropertyChanged(string propertyName)
        {
            PropertyChangedEventHandler handler = PropertyChanged;
            if (handler != null) handler(this, new PropertyChangedEventArgs(propertyName));
        }
    }
}

Example 2: how to implement FluentValidation in wpf

<Window
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:viewModels="clr-namespace:WpfFluentValidationExample.ViewModels" x:Class="WpfFluentValidationExample.Views.UserView"
        Title="UserView" Height="300" MinWidth="500">
    <Window.DataContext>
        <viewModels:UserViewModel/>
    </Window.DataContext>
    <StackPanel>
        <StackPanel Orientation="Horizontal">
            <Label Content="Name" Margin="10"/>
            <TextBox Text="{Binding Name, UpdateSourceTrigger=PropertyChanged, ValidatesOnDataErrors=True}" Width="200" Margin="10">
                <Validation.ErrorTemplate>
                    <ControlTemplate>
                        <StackPanel Orientation="Horizontal">
                            <!-- Placeholder for the TextBox itself -->
                            <AdornedElementPlaceholder x:Name="textBox"/>
                            <TextBlock Margin="10" Text="{Binding [0].ErrorContent}" Foreground="Red"/>
                        </StackPanel>
                    </ControlTemplate>
                </Validation.ErrorTemplate>
            </TextBox>
        </StackPanel>
        <StackPanel Orientation="Horizontal">
            <Label Content="E-Mail" Margin="10"/>
            <TextBox Text="{Binding Email, UpdateSourceTrigger=PropertyChanged, ValidatesOnDataErrors=True}" Width="200" Margin="10">
                <Validation.ErrorTemplate>
                    <ControlTemplate>
                        <StackPanel Orientation="Horizontal">
                            <!-- Placeholder for the TextBox itself -->
                            <AdornedElementPlaceholder x:Name="textBox"/>
                            <TextBlock Margin="10" Text="{Binding [0].ErrorContent}" Foreground="Red"/>
                        </StackPanel>
                    </ControlTemplate>
                </Validation.ErrorTemplate>
            </TextBox>
        </StackPanel>
        <StackPanel Orientation="Horizontal">
            <Label Content="Zip" Margin="10"/>
            <TextBox Text="{Binding Zip, UpdateSourceTrigger=PropertyChanged, ValidatesOnDataErrors=True}" Width="200" Margin="10">
                <Validation.ErrorTemplate>
                    <ControlTemplate>
                        <StackPanel Orientation="Horizontal">
                            <!-- Placeholder for the TextBox itself -->
                            <AdornedElementPlaceholder x:Name="textBox"/>
                            <TextBlock Margin="10" Text="{Binding [0].ErrorContent}" Foreground="Red"/>
                        </StackPanel>
                    </ControlTemplate>
                </Validation.ErrorTemplate>
            </TextBox>
        </StackPanel>
        <Button Margin="10">Submit</Button>
    </StackPanel>
</Window>