【问题标题】:PowerShell WPF DataGrid: Exception thrown committing empty rowPowerShell WPF DataGrid:提交空行时引发异常
【发布时间】:2010-10-15 22:44:13
【问题描述】:

我在尝试提交 empty DataGrid 行时遇到异常。

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."

重现步骤:

  • 转到“新行”
  • 按 F2
  • 按回车

这工作正常:

  • 转到“新行”
  • 按 F2
  • 按ESC

还有:

  • 转到“新行”
  • 按 F2
  • 键入“sdfdsf”
  • 按回车

来源可以在here找到。

我发现了两个帖子似乎与这个问题有关:

  1. Exception in .Net 3.5 SP1
  2. WPF Databinding, Class Types, No Namespace Exception

另外,我在 C# 中尝试了类似的代码,它运行良好。

我该如何解决这个问题?

【问题讨论】:

    标签: wpf powershell datagrid wpftoolkit


    【解决方案1】:

    这似乎是 Microsoft WPF DataGrid 中的一个错误。如果您还没有这样做,您绝对应该通过Microsoft Connect 报告它。

    作为一种解决方法,您可以在绑定上使用值转换器,以阻止绑定目标上的 NULL 值传输到绑定源,这将导致 NullReferenceException。以下是此类转换器的示例:

    // 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;
            }
        }
    }
    

    为了将转换器应用于您的绑定,您必须像这样修改您的 XAML:

    <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>
    

    或者,当输入值为字符串时,您可以修改 NullToUnsetConverter.Convert 方法以返回 空字符串,就像您的情况一样。

    【讨论】:

      猜你喜欢
      • 2015-12-14
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多