WPF DataGrid, application crash when adding row

I have a wpf datagrid related to TrackableCollection. In some rare cases, and only for a few selected users, the application will crash when the user adds a new entry by entering the bottom empty line. I could not reproduce the problem, and all I have is a stack from the exception thrown. Has anyone seen anything like this? I have limited knowledge about automation classes, but I can confirm that we do not use any of them in our application.

Here's the stacktrace:

System.ArgumentNullException: Value cannot be null. Parameter name: item at System.Windows.Automation.Peers.DataGridAutomationPeer.CreateItemAutomationPeer(Object item) at System.Windows.Automation.Peers.ItemsControlAutomationPeer.FindOrCreateItemAutomationPeer(Object item) at System.Windows.Automation.Peers.DataGridAutomationPeer.RaiseAutomationSelectionEvents(SelectionChangedEventArgs e) at System.Windows.Controls.DataGrid.OnSelectionChanged(SelectionChangedEventArgs e) at System.Windows.Controls.Primitives.Selector.SelectionChanger.End() at System.Windows.Controls.DataGrid.MakeFullRowSelection(Object dataItem, Boolean allowsExtendSelect, Boolean allowsMinimalSelect) at System.Windows.Controls.DataGrid.HandleSelectionForCellInput(DataGridCell cell, Boolean startDragging, Boolean allowsExtendSelect, Boolean allowsMinimalSelect) at System.Windows.Controls.DataGridCell.OnAnyMouseLeftButtonDown(MouseButtonEventArgs e) at System.Windows.RoutedEventArgs.InvokeHandler(Delegate handler, Object target) at System.Windows.EventRoute.InvokeHandlersImpl(Object source, RoutedEventArgs args, Boolean reRaised) at System.Windows.UIElement.ReRaiseEventAs(DependencyObject sender, RoutedEventArgs args, RoutedEvent newEvent) at System.Windows.RoutedEventArgs.InvokeHandler(Delegate handler, Object target) at System.Windows.EventRoute.InvokeHandlersImpl(Object source, RoutedEventArgs args, Boolean reRaised) at System.Windows.UIElement.RaiseEventImpl(DependencyObject sender, RoutedEventArgs args) at System.Windows.UIElement.RaiseTrustedEvent(RoutedEventArgs args) at System.Windows.Input.InputManager.ProcessStagingArea() at System.Windows.Input.InputProviderSite.ReportInput(InputReport inputReport) at System.Windows.Interop.HwndMouseInputProvider.ReportInput(IntPtr hwnd, InputMode mode, Int32 timestamp, RawMouseActions actions, Int32 x, Int32 y, Int32 wheel) at System.Windows.Interop.HwndMouseInputProvider.FilterMessage(IntPtr hwnd, WindowMessage msg, IntPtr wParam, IntPtr lParam, Boolean& handled) at System.Windows.Interop.HwndSource.InputFilterMessage(IntPtr hwnd, Int32 msg, IntPtr wParam, IntPtr lParam, Boolean& handled) at MS.Win32.HwndWrapper.WndProc(IntPtr hwnd, Int32 msg, IntPtr wParam, IntPtr lParam, Boolean& handled) at MS.Win32.HwndSubclass.DispatcherCallbackOperation(Object o) at System.Windows.Threading.ExceptionWrapper.InternalRealCall(Delegate callback, Object args, Int32 numArgs) at MS.Internal.Threading.ExceptionFilterHelper.TryCatchWhen(Object source, Delegate method, Object args, Int32 numArgs, Delegate catchHandler) 

XAML:

 <DataGrid Name="OrdreSLinjeGrid" AutoGenerateColumns="False" CanUserResizeRows="False" CanUserAddRows="{Binding KanLeggeTilOrdreLinjer}" HorizontalScrollBarVisibility="Disabled" VerticalScrollBarVisibility="Visible" ItemsSource="{Binding Order.OrderLines, Mode=TwoWay}" CanUserSortColumns="False" SelectedItem="{Binding ValgtOrdreLinje}" > <DataGrid.Columns> <DataGridTextColumn Header="{t:Translate Antall}" TextAlignment="Right" Width="50" HeaderStyle="{StaticResource HøyrejustertColumnHeader}" Binding="{Binding Antall, UpdateSourceTrigger=LostFocus}" /> <DataGridTextColumn Header="{t:Translate Pris}" Width="60" HeaderStyle="{StaticResource HøyrejustertColumnHeader}" Binding="{Binding Pris, UpdateSourceTrigger=LostFocus, ValidatesOnDataErrors=True}" /> </DataGrid.Columns> </DataGrid> 

Any input or suggestions would be appreciated.

+9
source share
6 answers

The problem is due to an error in the internal method DataGridAutomationPeer.RaiseAutomationSelectionEvents , which simply does not check whether the SelectedItem property is null or not. It can be easily played back by running the Microsoft storyteller tool in Windows 7.

Since this is a sealed class, there is no easy way to fix it other than intercepting this method using Reflection.Emit or any of the taunting tools, and even if it is fixed, we have no guarantee that Microsoft will not change this method name, signature, or behavior.

I implemented the “good enough” fix, inheriting from the DataGrid, which will change the way that the DataGrid is not selected when SelectedItem is null, but only if the narrator / touch screen is present.

I hope the bug will be fixed soon. Add a link to the UIAutomationProvider if necessary.

 using System.Windows.Automation.Peers; using System.Windows.Controls; public class TooDataGrid: DataGrid { protected override void OnSelectionChanged(SelectionChangedEventArgs e) { if(AutomationPeer.ListenerExists(AutomationEvents.SelectionItemPatternOnElementSelected) || AutomationPeer.ListenerExists(AutomationEvents.SelectionItemPatternOnElementAddedToSelection) || AutomationPeer.ListenerExists(AutomationEvents.SelectionItemPatternOnElementRemovedFromSelection)) { if(SelectedItem == null) { return; } } base.OnSelectionChanged(e); } } 
+9
source

I know this is pretty old, but there is a good solution to this problem that I am facing. You can define your own converter using the IValueConverter interface:

 public class SelectedItemConverter : IValueConverter { public object Convert(object value, Type targetType, object parameter, CultureInfo culture) { return value ?? DependencyProperty.UnsetValue; } public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture) { return (value == null || value.GetType().Name == "NamedObject") ? null : value; } } 

This checks to see if there is a null value, and if it is, returns DependecyProperty.UnsetValue . As described in the documentation (see method descriptions):

The return value of DependencyProperty.UnsetValue indicates that the converter did not receive any value and that the binding uses FallbackValue, if available, or the default value.

Returning rather than null should fix the problem.

+4
source

No need for converters or to use a derived class. Just make sure that the property you are binding to for SelectedItem is initialized with DependencyProperty.UnsetValue. Do not set it and do not leave it at default at zero.

The main error should be fixed in the near future, by the way: https://developercommunity.visualstudio.com/content/problem/575165/vs-1604-ide-crash-argumentnullexception.html

+2
source

I would try to check for zeros in your properties in your view model. If the property is NULL, replace null with a valid value of 0 or a space.

You can also do this with Value Converter

+1
source

I had the same problem with the touch screen. I had a WPF application that worked fine until I connected the touch screen for which the application was created.

This problem occurs when the selected DataGrid is limited to an object that was null;

I solved it like this:

The DataGrid Xaml had the following line:

 SelectedItem="{Binding SelItem}" 

XVVM looked like this:

 public MyViewModel SelItem { get { if (m_selected == null) return new MyViewModel(); else return m_selected; } } 
+1
source

I have the same problem. This happens in Datagrid when the user double-clicks the first row in the DataGrid (with only one row). This only happens on a Sony laptop with a touch screen. Sony software adds check boxes to each file in Winfows Explorer. I think this problem is related to sony software.

0
source

All Articles