I observed a very strange issue related to WPF DataGrid validation that occurs only in some conditions. To reproduce the issue I have a test window.
<Window x:Class="TEST.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:TEST"
mc:Ignorable="d"
Title="MainWindow" Height="450" Width="800">
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="*"></RowDefinition>
<RowDefinition Height="Auto">
</RowDefinition>
</Grid.RowDefinitions>
<DataGrid x:Name="datagrid" AutoGenerateColumns="True" Grid.Row="0" ColumnWidth="*"></DataGrid>
<Button Click="Button_Click" Grid.Row="1">Fill Data</Button>
</Grid>
</Window>
And this is the code behind:
namespace TEST
{
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
}
ObservableCollection<Person> list = null;
private void Button_Click(object sender, RoutedEventArgs e)
{
list= new ObservableCollection<Person>();
for (int i = 0; i < 100; i++)
{
list.Add(new Person() { Age = 20, Name = "Person"+i.ToString()});
}
datagrid.ItemsSource = list;
}
}
public class Person
{
public string Name { get; set; }
public int Age { get; set; }
}
}
When I write a non numeric value for a cell under Age column, the cell gets a red border to show the error. But without correcting that error, if I populate the DataGrid with a new list the error disappears as expected. Now, if I enter an Age cell and right click, then click another row before closing the combobox that exception is thrown:
System.ArgumentNullException: 'Value cannot be null. Parameter name: element' This exception was originally thrown at this call stack: System.Windows.Automation.Peers.UIElementAutomationPeer.FromElement(System.Windows.UIElement) System.Windows.Controls.DataGrid.CellAutomationValueHolder.TrackValue() System.Windows.Controls.DataGrid.ReleaseCellAutomationValueHolders() System.Windows.Controls.DataGrid.OnExecutedCommitEdit(System.Windows.Input.ExecutedRoutedEventArgs) System.Windows.Controls.DataGrid.OnExecutedCommitEdit(object, System.Windows.Input.ExecutedRoutedEventArgs) System.Windows.Input.CommandBinding.OnExecuted(object, System.Windows.Input.ExecutedRoutedEventArgs) System.Windows.Input.CommandManager.ExecuteCommandBinding(object, System.Windows.Input.ExecutedRoutedEventArgs, System.Windows.Input.CommandBinding) System.Windows.Input.CommandManager.FindCommandBinding(object, System.Windows.RoutedEventArgs, System.Windows.Input.ICommand, bool) System.Windows.Input.CommandManager.OnExecuted(object, System.Windows.Input.ExecutedRoutedEventArgs) System.Windows.UIElement.OnExecutedThunk(object, System.Windows.Input.ExecutedRoutedEventArgs)
The stack trace doesn't have clear information about the issue and that exception can be raised some other cell click / edits other than the test above. The common point is that WPF DataGrid tends to keep references to previous ItemSource object especially when there are validation errors. I have tried using other IEnumerable types and moving the ObservableCollection definition into the button click event but the result is same.
How can I clear validation error references and make the DataGrid forget about the previous ItemSource objects?
Thanks.