PowerShell WPF DataGrid: exception throwing an empty row

I get an exception trying to execute an empty DataGrid row.

System.NullReferenceException: Object reference not set to an instance of an object. at MS.Internal.Data.PropertyPathWorker.DetermineWhetherDBNullIsValid() at MS.Internal.Data.PropertyPathWorker.get_IsDBNullValidForUpdate() at MS.Internal.Data.ClrBindingWorker.get_IsDBNullValidForUpdate() at System.Windows.Data.BindingExpression.ConvertProposedValue(Object value) at System.Windows.Data.BindingExpressionBase.UpdateValue() at System.Windows.Data.BindingExpression.Update(Boolean synchronous) at System.Windows.Data.BindingExpression.UpdateSource() at Microsoft.Windows.Controls.DataGridHelper.UpdateSource(FrameworkElement element, DependencyProperty dp) at Microsoft.Windows.Controls.DataGridTextColumn.CommitCellEdit(FrameworkElement editingElement) at Microsoft.Windows.Controls.DataGridColumn.CommitEdit(FrameworkElement editingElement) at Microsoft.Windows.Controls.DataGridCell.CommitEdit() at Microsoft.Windows.Controls.DataGrid.OnExecutedCommitEdit(ExecutedRoutedEventArgs e) at Microsoft.Windows.Controls.DataGrid.OnExecutedCommitEdit(Object sender, ExecutedRoutedEventArgs e) at System.Windows.Input.CommandBinding.OnExecuted(Object sender, ExecutedRoutedEventArgs e) at System.Windows.Input.CommandManager.ExecuteCommandBinding(Object sender, ExecutedRoutedEventArgs e, CommandBinding commandBinding) at System.Windows.Input.CommandManager.FindCommandBinding(CommandBindingCollection commandBindings, Object sender, RoutedEventArgs e, ICommand command, Boolean execute) at System.Windows.Input.CommandManager.FindCommandBinding(Object sender, RoutedEventArgs e, ICommand command, Boolean execute) at System.Windows.Input.CommandManager.OnExecuted(Object sender, ExecutedRoutedEventArgs e) at System.Windows.UIElement.OnExecutedThunk(Object sender, ExecutedRoutedEventArgs e) at System.Windows.Input.ExecutedRoutedEventArgs.InvokeEventHandler(Delegate genericHandler, Object target) at System.Windows.RoutedEventArgs.InvokeHandler(Delegate handler, Object target) at System.Windows.RoutedEventHandlerInfo.InvokeHandler(Object target, RoutedEventArgs routedEventArgs) at System.Windows.EventRoute.InvokeHandlersImpl(Object source, RoutedEventArgs args, Boolean reRaised) at System.Windows.UIElement.RaiseEventImpl(DependencyObject sender, RoutedEventArgs args) at System.Windows.UIElement.RaiseEvent(RoutedEventArgs args, Boolean trusted) at System.Windows.Input.RoutedCommand.ExecuteImpl(Object parameter, IInputElement target, Boolean userInitiated) at System.Windows.Input.RoutedCommand.Execute(Object parameter, IInputElement target) at Microsoft.Windows.Controls.DataGrid.EndEdit(RoutedCommand command, DataGridCell cellContainer, DataGridEditingUnit editingUnit, Boolean exitEditMode) at Microsoft.Windows.Controls.DataGrid.CommitEdit(DataGridEditingUnit editingUnit, Boolean exitEditingMode) at Microsoft.Windows.Controls.DataGrid.CommitAnyEdit() at Microsoft.Windows.Controls.DataGrid.OnEnterKeyDown(KeyEventArgs e) at Microsoft.Windows.Controls.DataGrid.OnKeyDown(KeyEventArgs e) at System.Windows.UIElement.OnKeyDownThunk(Object sender, KeyEventArgs e) at System.Windows.Input.KeyEventArgs.InvokeEventHandler(Delegate genericHandler, Object genericTarget) at System.Windows.RoutedEventArgs.InvokeHandler(Delegate handler, Object target) at System.Windows.RoutedEventHandlerInfo.InvokeHandler(Object target, RoutedEventArgs routedEventArgs) at System.Windows.EventRoute.InvokeHandlersImpl(Object source, RoutedEventArgs args, Boolean reRaised) at System.Windows.UIElement.RaiseEventImpl(DependencyObject sender, RoutedEventArgs args) at System.Windows.UIElement.RaiseEvent(RoutedEventArgs args, Boolean trusted) at System.Windows.Input.InputManager.ProcessStagingArea() at System.Windows.Input.InputManager.ProcessInput(InputEventArgs input) at System.Windows.Input.InputProviderSite.ReportInput(InputReport inputReport) at System.Windows.Interop.HwndKeyboardInputProvider.ReportInput(IntPtr hwnd, InputMode mode, Int32 timestamp, RawKeyboardActions actions, Int32 scanCode, Boolean isExtendedKey, Boolean isSystemKey, Int32 virtualKey) at System.Windows.Interop.HwndKeyboardInputProvider.ProcessKeyAction(MSG& msg, Boolean& handled) at System.Windows.Interop.HwndSource.CriticalTranslateAccelerator(MSG& msg, ModifierKeys modifiers) at System.Windows.Interop.HwndSource.OnPreprocessMessage(Object param) at System.Windows.Threading.ExceptionWrapper.InternalRealCall(Delegate callback, Object args, Boolean isSingleParameter) at System.Windows.Threading.ExceptionWrapper.TryCatchWhen(Object source, Delegate callback, Object args, Boolean isSingleParameter, Delegate catchHandler) Exception calling "Run" with "1" argument(s): "Object reference not set to an instance of an object." 

Steps to play:

  • Go to the "new line"
  • Press F2
  • Press ENTER

This works fine:

  • Go to the "new line"
  • Press F2
  • Press esc

As well as:

  • Go to the "new line"
  • Press F2
  • Enter "sdfdsf"
  • Press ENTER

Sources can be found here .

I found two posts that seem to be related to this problem:

In addition, I tried similar code in C # and it worked fine.

How can I fix this problem?

+4
source share
1 answer

This seems to be a bug in Microsoft DataGrid Microsoft WPF. You must report this via Microsoft Connect if you have not already.

As a workaround, you can use the value converter in your bindings to stop the NULL values ​​in the target binding that will be carried to the binding source, which will throw a NullReferenceException . Here is an example of such a converter:

 // NullToUnsetConverter.cs using System; using System.Windows; using System.Windows.Data; using System.Globalization; namespace MyProject.Controls.Converters { /// <summary> /// Converts <c>null</c> values to <see cref="DependencyProperty.UnsetValue"/>. /// <remarks> /// This converter is intented for use in situations when the binding target /// does not correctly handle <c>null</c> values. This is the case for example /// with some WPF UI controls. /// </remarks> /// </summary> public class NullToUnsetConverter : IValueConverter { public object Convert(object value, Type targetType, object parameter, CultureInfo culture) { if (value == null) { return DependencyProperty.UnsetValue; } else { // No conversion applied return value; } } public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture) { // No conversion applied return value; } } } 

To apply the converter to your bindings, you will need to change your XAML as follows:

 <Window xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:cnv="clr-namespace:MyProject.Controls.Converters" xmlns:sys="clr-namespace:System;assembly=mscorlib" xmlns:dg="clr-namespace:Microsoft.Windows.Controls;assembly=WpfToolkit" > <Window.Resources> <x:Array x:Key="people" Type="sys:Object" /> <cnv:NullToUnsetConverter x:Key="NullToUnsetConverter" /> </Window.Resources> <StackPanel> <dg:DataGrid ItemsSource="{DynamicResource people}" CanUserAddRows="True" AutoGenerateColumns="False"> <dg:DataGrid.Columns> <dg:DataGridTextColumn Header="First" Binding="{Binding First, Converter={StaticResource NullToUnsetConverter}}" /> <dg:DataGridTextColumn Header="Last" Binding="{Binding Last, Converter={StaticResource NullToUnsetConverter}}" /> </dg:DataGrid.Columns> </dg:DataGrid> </StackPanel> </Window> 

Alternatively, you can change the NullToUnsetConverter.Convert method to return an empty string when the input value is a string, for example, in your case.

+2
source

All Articles