我有一个绑定到TrackableCollection的wpf数据网格。在一些罕见的情况下,对于少数选定的用户,当用户通过输入底部空白行添加新记录时,应用程序将崩溃。 我无法重现这个问题,而我所拥有的只是抛出异常的堆栈跟踪。 有没有人见过这样的东西?我对automationpeer-classes的了解有限,但我可以确认我们的应用程序中没有使用它们。
这是堆栈跟踪:
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>
任何意见或建议都将受到赞赏。
答案 0 :(得分:9)
问题与DataGridAutomationPeer.RaiseAutomationSelectionEvents
内部方法中的错误有关,简单来说,不会检查SelectedItem属性是否为null。它可以通过运行&#34; Microsoft Narrator&#34;轻松复制。 Windows 7中的工具。
因为这是一个密封的类,除了使用Reflection.Emit或任何模拟工具拦截这个方法之外没有简单的方法来修复它,即使它被修复了,我们也无法保证微软赢得了#。 t更改此方法名称,签名或行为。
我实施了足够好的&#34;&#34;通过继承DataGrid进行修复,当SelectedItem为null时,它将改变DataGrid的取消方式,但仅当存在narrator / touchscreen时才会被取消。
希望错误很快得到修复。如有必要,请添加对UIAutomationProvider的引用。
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);
}
}
答案 1 :(得分:4)
我知道这已经很老了,但是我遇到了这个问题的一个很好的解决方案。您可以使用IValueConverter
界面定义自定义转换器:
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;
}
}
检查值是null
,如果是,则返回DependecyProperty.UnsetValue
。如documentation中所述(查看方法描述):
DependencyProperty.UnsetValue的返回值表示转换器未生成任何值,并且绑定使用FallbackValue(如果可用)或默认值。
返回此而不是null
应解决此问题。
答案 2 :(得分:2)
无需转换器或使用派生类。 只需确保使用DependencyProperty.UnsetValue初始化您为SelectedItem绑定的属性。不要将其设置为或保留默认值为null。
答案 3 :(得分:1)
我会尝试在视图模型中检查属性上的空值。如果属性为null,则将null替换为有效值,如0或空白。
您也可以使用值转换器
执行此操作答案 4 :(得分:1)
我的触摸屏只有同样的问题。 我有一个WPF应用程序工作正常,直到我连接了应用程序的触摸屏。
当DataGrid选定项被绑定到一个为null的对象时,会出现此问题;
我这样解决了:
DataGrid Xaml有这一行:
SelectedItem="{Binding SelItem}"
XVVM看起来像:
public MyViewModel SelItem
{
get
{
if (m_selected == null)
return new MyViewModel();
else
return m_selected;
}
}
答案 5 :(得分:0)
我有同样的问题。当用户双击DataGrid中的第一行(只有一行)时,它出现在Datagrid上。这仅在具有触摸屏的Sony笔记本电脑上发生。 Sony软件为Winfows Explorer中的每个文件添加了复选框。我认为这个问题与索尼软件有关。