title: WPF UI controls not validating correctly on ErrorsChanged event
body: <p>I have the following INotifyDataErrorInfo implementation in an abstract base class.</p>
  
  <pre><code>    private IEnumerable&lt;ValidationErrorModel&gt; _validationErrors = new List&lt;ValidationErrorModel&gt;();
      public IEnumerable&lt;ValidationErrorModel&gt; ValidationErrors
      {
          get { return _validationErrors; }
          private set
          {
              _validationErrors = value;
              OnPropertyChanged();
          }
      }
  
      protected abstract Task&lt;ValidationResult&gt; GetValidationResultAsync();
  
      public IEnumerable GetErrors(string propertyName)
      {
          if (string.IsNullOrEmpty(propertyName) ||
              ValidationErrors == null)
              return null;
  
          IEnumerable&lt;string&gt; errors = ValidationErrors
              .Where(p =&gt; p.PropertyName.Equals(propertyName))
              .Select(p =&gt; p.ToString())
              .ToList();
  
          return errors;
      }
  
      public bool HasErrors
      {
          get
          {
              bool hasErrors = ValidationErrors != null &amp;&amp; ValidationErrors.Any();
              return hasErrors;
          }
      }
  
      public Task&lt;ValidationResult&gt; ValidateAsync()
      {
          Task&lt;ValidationResult&gt; validationResultTask = GetValidationResultAsync();
  
          validationResultTask.ContinueWith((antecedent) =&gt;
          {
              if (antecedent.IsCompleted &amp;&amp;
                  !antecedent.IsCanceled &amp;&amp;
                  !antecedent.IsFaulted)
              {
                  ValidationResult validationResult = antecedent.Result;
                  if (validationResult != null)
                  {
                      lock (ValidationErrors)
                      {
                          ValidationErrors =
                              validationResult.Errors
                                  .Select(validationFailure =&gt;
                                      new ValidationErrorModel(validationFailure.PropertyName, validationFailure.ErrorMessage))
                                      .ToList();
  
                          foreach (ValidationErrorModel validationErrorModel in ValidationErrors)
                          {
                              RaiseErrorsChanged(validationErrorModel.PropertyName);
                          }
                      }
                  }
              }
          });
          return validationResultTask;
      }
  
      public event EventHandler&lt;DataErrorsChangedEventArgs&gt; ErrorsChanged = delegate { };
  
      protected virtual void RaiseErrorsChanged(string propertyName)
      {
          var handler = ErrorsChanged;
          if (handler != null)
          {
              Dispatcher.InvokeOnMainThread(() =&gt;
              {
                  handler(this, new DataErrorsChangedEventArgs(propertyName));
              });
          }
      }
  </code></pre>
  
  <p>In models deriving from the base class I implement the <code>Task&lt;ValidationResult&gt; GetValidationResultAsync()</code> required method, it uses fluent validation Nuget package.</p>
  
  <pre><code>    private readonly ModelValidator _modelValidator = new ModelValidator();
  
      protected override Task&lt;ValidationResult&gt; GetValidationResultAsync()
      {
          return _modelValidator.ValidateAsync(this);
      }
  </code></pre>
  
  <p>The problem is that when I invoke from a ViewModel the <code>ValidateAsync()</code> method of a model the UI input controls are not invalidate/validate correctly, I actually have a tab control and validate the models in tab index changed, some might show the red border once I change tab but then again return to normal state to the next tab change.</p>
  
  <p>In debug it shows that the <code>ValidationErrors</code> property returns errors.</p>
  
  <p>My XAML input controls code is like below.</p>
  
  <pre><code>    &lt;Grid&gt;
          &lt;StackPanel&gt;
              &lt;StackPanel Orientation="Horizontal"&gt;
                  &lt;TextBlock Text="Name:"/&gt;
                  &lt;TextBox Text="{Binding Name, UpdateSourceTrigger=PropertyChanged, Mode=TwoWay, ValidatesOnNotifyDataErrors=True}" Width="200"/&gt;
              &lt;/StackPanel&gt;
              &lt;StackPanel Orientation="Horizontal"&gt;
                  &lt;TextBlock Text="Scheduled Date:"/&gt;
                  &lt;DatePicker DisplayDate="{Binding ScheduledDate, UpdateSourceTrigger=PropertyChanged, Mode=TwoWay, ValidatesOnNotifyDataErrors=True}"/&gt;
              &lt;/StackPanel&gt;
          &lt;/StackPanel&gt;
      &lt;/Grid&gt;
  </code></pre>
  
  <p><strong>[Update 1]</strong></p>
  
  <p>I should mention that I use in the <code>MainWindow</code> a tab control and 3 tab items, each tab item is a UserControl.</p>
  
  <p>I hooked up to the Validation.Error event of all the XAML UserControls and I noticed that even I get tab selected index changed value the Validation.Error fires once for the first tab and never again, I suspect there is a cleanup somewhere for a reason.</p>
  
  <p>Code for the SelectedTabIndex that fires the models validations.</p>
  
  <pre><code>        private int _selectedTabIndex = 0;
          public int SelectedTabIndex
          {
              get { return _selectedTabIndex; }
              set
              {
                  _selectedTabIndex = value;
                  ValidateModels();
                  Tab2ViewModel.ValidateModels();
                  Tab3ViewModel.ValidateModels();
                  OnPropertyChanged();
              }
          }
  </code></pre>
  
  <p>The <code>ValidateModels</code> method calls <code>ValidateAsync</code> of the model in the ViewModel.</p>
  
  <pre><code>        public override Task ValidateModels()
          {
              return Model.ValidateAsync();
          }
  </code></pre>
  
  <p>MainWindow TabControl XAML.</p>
  
  <pre><code>&lt;TabControl SelectedIndex="{Binding SelectedTabIndex, Mode=TwoWay}"&gt;
  </code></pre>
  
  <p><strong>[Update 2]</strong></p>
  
  <p>After adding a custom error style and a custom error template, I see that the controls tooltip stay with the condition not met error but the error template is clearing. So, the TextBox shows no error template, custom or default, but the validation error exists and the tooltip shows the error.</p>
  
  <p>Why the XAML templates clear on TabIndexChange and how come they don't refresh at least on the active tab item I'm viewing. This might be the problem that I should solve.</p>
  
  <p>Also, as mentioned before, I don't see the ErrorsChanged revalidating the controls except the first time the SelectedTabIndex setter is invoked.</p>
  
  <p>The templates I added.</p>
  
  <pre><code>&lt;Application.Resources&gt;
          &lt;Style x:Key="ErrorStyle"
                 TargetType="FrameworkElement"&gt;
              &lt;Style.Triggers&gt;
                  &lt;Trigger Property="Validation.HasError" Value="True"&gt;
                      &lt;Setter Property="ToolTip" Value="{Binding (Validation.Errors).CurrentItem.ErrorContent, RelativeSource={x:Static RelativeSource.Self}}"&gt;&lt;/Setter&gt;
                  &lt;/Trigger&gt;
              &lt;/Style.Triggers&gt;
          &lt;/Style&gt;
          &lt;ControlTemplate x:Key="TextBoxErrorTemplate"&gt;
              &lt;DockPanel&gt;
                  &lt;Ellipse DockPanel.Dock="Right"
                           Margin="2,0"
                           ToolTip="Contains Invalid Data"
                           Width="10"
                           Height="10"
                           &gt;
                      &lt;Ellipse.Fill&gt;
                          &lt;LinearGradientBrush&gt;
                              &lt;GradientStop Color="#11FF1111" Offset="0"/&gt;
                              &lt;GradientStop Color="#FFFF0000" Offset="1"/&gt;
                          &lt;/LinearGradientBrush&gt;
                      &lt;/Ellipse.Fill&gt;
                  &lt;/Ellipse&gt;
                  &lt;AdornedElementPlaceholder/&gt;
              &lt;/DockPanel&gt;
          &lt;/ControlTemplate&gt;
          &lt;Style TargetType="TextBox"&gt;
              &lt;Setter Property="Margin" Value="4,4,15,4"/&gt;
              &lt;Setter Property="Validation.ErrorTemplate" Value="{StaticResource TextBoxErrorTemplate}"/&gt;
              &lt;Style.Triggers&gt;
                      &lt;Trigger Property="Validation.HasError" Value="True"&gt;
                          &lt;Setter Property="ToolTip"&gt;
                              &lt;Setter.Value&gt;
                                  &lt;Binding Path="(Validation.Errors).CurrentItem.ErrorContent" RelativeSource="{x:Static RelativeSource.Self}"/&gt;
                              &lt;/Setter.Value&gt;
                          &lt;/Setter&gt;
                      &lt;/Trigger&gt;
              &lt;/Style.Triggers&gt;
          &lt;/Style&gt;
      &lt;/Application.Resources&gt;
  </code></pre>