I have a WPF application built with .NET Framework 4.8. I have a viewmodel that implements INotifyDataErrorInfo for validation. In my XAML I am using the default Validation.ErrorTemplate, but I have also tried using a custom template with the same results.
If I only have a few controls with validation errors, the default WPF validation adorners appear correctly. If have a lot of controls with validation errors the adorners do not always appear around the AdornedElement.
Here is a sample application that demonstrates the issue:
ViewModel.cs
public class ViewModel: INotifyPropertyChanged, INotifyDataErrorInfo
{
private string _value;
public string Value
{
get { return _value; }
set
{
_value = value;
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(nameof(Value)));
}
}
public event PropertyChangedEventHandler PropertyChanged;
public IEnumerable GetErrors(string propertyName)
{
return new[]{"Value cannot be null"};
}
public bool HasErrors
{
get
{
return string.IsNullOrEmpty(_value);
}
}
public event EventHandler<DataErrorsChangedEventArgs> ErrorsChanged;
}
MainWindow.xaml <
Window x:Class="ValidationErrorProblem.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
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"
xmlns:local="clr-namespace:ValidationErrorProblem"
mc:Ignorable="d"
Title="MainWindow" Height="800" Width="400">
<Grid>
<ScrollViewer HorizontalAlignment="Right">
<ItemsControl x:Name="MyList">
<ItemsControl.ItemTemplate>
<DataTemplate DataType="{x:Type local:ViewModel}">
<TextBox Margin="5" Text="{Binding Value}" Width="100"/>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
</ScrollViewer>
</Grid>
</Window>
MainWindow.xaml.cs
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
var items = new List<ViewModel>();
for (var i = 0; i < 200; i++) items.Add(new ViewModel());
MyList.ItemsSource = items;
}
}
Here is what it looks like when run the application and start scrolling:
If I resize the window after I scroll, it temporarily fixes the adorner placements. But as soon as I scroll again, I get the same problem.
I can fix this if I wrap the TextBox in its own AdornerDecorator. But my actual application contains multiple UserControls that each have hundreds of unique controls (TextBoxes, ComboBoxes, ToggleButtons, etc) that are not created from a template. I do not want to have to update my XAML to add more AdornerDecorators, especially not one for each control.
This seems like a bug in .Net Framework (4.8). Does anyone else have this problem, and have you found a simple fix?