提问人:MatsW 提问时间:12/14/2021 最后编辑:MatsW 更新时间:12/15/2021 访问量:340
为什么 datagrid 在失去焦点时会引发异常?
Why is datagrid raising exception when loosing focus?
问:
我想我在 DataGrid 中发现了一个错误。我在 WPF (.net 5.0) 中遇到看似无法解释的数据网格崩溃
你能发现我做错了什么吗?我不能...我现在花了很多天的时间,代码非常清楚。
如何崩溃:
- 生成并运行下面给出的代码。
- 编辑“数据”网格单元格,将光标保留在单元格文本框中
- 从菜单中选择更新。(单元格将恢复为“数据”)
- 再次编辑“数据”网格单元格,将光标留在单元格文本框中
- 单击“TabItem”标题 ->异常如下所示:
System.ArgumentNullException
HResult=0x80004003
Message=Value cannot be null. (Parameter 'element')
Source=PresentationCore
StackTrace:
at System.Windows.Automation.Peers.UIElementAutomationPeer.FromElement(UIElement element)
at System.Windows.Controls.DataGrid.CellAutomationValueHolder.TrackValue()
at System.Windows.Controls.DataGrid.ReleaseCellAutomationValueHolders()
at System.Windows.Controls.DataGrid.OnExecutedCommitEdit(ExecutedRoutedEventArgs e)
at System.Windows.Controls.DataGrid.OnExecutedCommitEdit(Object sender, ExecutedRoutedEventArgs e)
at System.Windows.Input.CommandBinding.OnExecuted(Object sender, ExecutedRoutedEventArgs e)
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.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.Input.RoutedCommand.ExecuteImpl(Object parameter, IInputElement target, Boolean userInitiated)
at System.Windows.Input.RoutedCommand.Execute(Object parameter, IInputElement target)
at System.Windows.Controls.DataGrid.EndEdit(RoutedCommand command, DataGridCell cellContainer, DataGridEditingUnit editingUnit, Boolean exitEditMode)
at System.Windows.Controls.DataGrid.OnCurrentCellChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
at System.Windows.FrameworkElement.OnPropertyChanged(DependencyPropertyChangedEventArgs e)
at System.Windows.DependencyObject.NotifyPropertyChange(DependencyPropertyChangedEventArgs args)
at System.Windows.DependencyObject.UpdateEffectiveValue(EntryIndex entryIndex, DependencyProperty dp, PropertyMetadata metadata, EffectiveValueEntry oldEntry, EffectiveValueEntry& newEntry, Boolean coerceWithDeferredReference, Boolean coerceWithCurrentValue, OperationType operationType)
at System.Windows.DependencyObject.SetValueCommon(DependencyProperty dp, Object value, PropertyMetadata metadata, Boolean coerceWithDeferredReference, Boolean coerceWithCurrentValue, OperationType operationType, Boolean isInternal)
at System.Windows.DependencyObject.SetCurrentValueInternal(DependencyProperty dp, Object value)
at System.Windows.Controls.DataGrid.set_CurrentCellContainer(DataGridCell value)
at System.Windows.Controls.DataGrid.set_FocusedCell(DataGridCell value)
at System.Windows.Controls.DataGridCell.OnAnyLostFocus(Object sender, RoutedEventArgs e)
at System.Windows.EventRoute.InvokeHandlersImpl(Object source, RoutedEventArgs args, Boolean reRaised)
at System.Windows.UIElement.RaiseEventImpl(DependencyObject sender, RoutedEventArgs args)
at System.Windows.UIElement.OnLostFocus(RoutedEventArgs e)
at System.Windows.Controls.Primitives.TextBoxBase.OnLostFocus(RoutedEventArgs e)
at System.Windows.FrameworkElement.OnPropertyChanged(DependencyPropertyChangedEventArgs e)
at System.Windows.Controls.TextBox.OnPropertyChanged(DependencyPropertyChangedEventArgs e)
at System.Windows.DependencyObject.NotifyPropertyChange(DependencyPropertyChangedEventArgs args)
at System.Windows.DependencyObject.UpdateEffectiveValue(EntryIndex entryIndex, DependencyProperty dp, PropertyMetadata metadata, EffectiveValueEntry oldEntry, EffectiveValueEntry& newEntry, Boolean coerceWithDeferredReference, Boolean coerceWithCurrentValue, OperationType operationType)
at System.Windows.DependencyObject.ClearValueCommon(EntryIndex entryIndex, DependencyProperty dp, PropertyMetadata metadata)
at System.Windows.DependencyObject.ClearValue(DependencyPropertyKey key)
at System.Windows.Input.FocusManager.OnFocusedElementChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
at System.Windows.FrameworkElement.OnPropertyChanged(DependencyPropertyChangedEventArgs e)
at System.Windows.DependencyObject.NotifyPropertyChange(DependencyPropertyChangedEventArgs args)
at System.Windows.DependencyObject.UpdateEffectiveValue(EntryIndex entryIndex, DependencyProperty dp, PropertyMetadata metadata, EffectiveValueEntry oldEntry, EffectiveValueEntry& newEntry, Boolean coerceWithDeferredReference, Boolean coerceWithCurrentValue, OperationType operationType)
at System.Windows.DependencyObject.SetValueCommon(DependencyProperty dp, Object value, PropertyMetadata metadata, Boolean coerceWithDeferredReference, Boolean coerceWithCurrentValue, OperationType operationType, Boolean isInternal)
at System.Windows.DependencyObject.SetValue(DependencyProperty dp, Object value)
at System.Windows.Input.FocusManager.SetFocusedElement(DependencyObject element, IInputElement value)
at System.Windows.Input.KeyboardNavigation.UpdateFocusedElement(DependencyObject focusTarget)
at System.Windows.FrameworkElement.OnGotKeyboardFocus(Object sender, KeyboardFocusChangedEventArgs 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.RaiseEventImpl(DependencyObject sender, RoutedEventArgs args)
at System.Windows.UIElement.RaiseTrustedEvent(RoutedEventArgs args)
at System.Windows.Input.InputManager.ProcessStagingArea()
at System.Windows.Input.KeyboardDevice.ChangeFocus(DependencyObject focus, Int32 timestamp)
at System.Windows.Input.KeyboardDevice.Focus(DependencyObject focus, Boolean askOld, Boolean askNew, Boolean forceToNullIfFailed)
at System.Windows.Input.KeyboardDevice.Focus(IInputElement element)
at System.Windows.UIElement.Focus()
at System.Windows.Controls.TabItem.SetFocus()
at System.Windows.Controls.TabItem.OnMouseLeftButtonDown(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 System.Windows.Threading.ExceptionWrapper.TryCatchWhen(Object source, Delegate callback, Object args, Int32 numArgs, Delegate catchHandler)
at System.Windows.Threading.Dispatcher.LegacyInvokeImpl(DispatcherPriority priority, TimeSpan timeout, Delegate method, Object args, Int32 numArgs)
at MS.Win32.HwndSubclass.SubclassWndProc(IntPtr hwnd, Int32 msg, IntPtr wParam, IntPtr lParam)
at MS.Win32.UnsafeNativeMethods.DispatchMessage(MSG& msg)
at System.Windows.Threading.Dispatcher.PushFrameImpl(DispatcherFrame frame)
at System.Windows.Threading.Dispatcher.PushFrame(DispatcherFrame frame)
at System.Windows.Threading.Dispatcher.Run()
at System.Windows.Application.RunDispatcher(Object ignore)
at System.Windows.Application.RunInternal(Window window)
at System.Windows.Application.Run()
at datagridcrashtest2.App.Main()
源代码:
using System;
using System.Windows;
using System.Windows.Input;
using System.Collections.ObjectModel;
using System.ComponentModel;
using System.Runtime.CompilerServices;
namespace DataGridTest
{
public class DataGridTest
{
static string xaml = @"
<Window x:Class=""System.Windows.Window""
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""
mc:Ignorable=""d""
Title=""DataGridTest"" Height=""650"" Width=""925"">
<StackPanel >
<Menu>
<MenuItem Header=""File"" >
<MenuItem Header=""Save"" Command=""{Binding UpdateCommand}"" />
<Button Command=""{Binding UpdateCommand}"" Content=""Update"" />
</MenuItem>
<Button Command=""{Binding UpdateCommand}"" Content=""Update"" />
</Menu>
<TabControl >
<TabItem Header=""TabItem"" Width=""150"" DataContext=""{Binding TabItemViewModel}"" >
<DataGrid ItemsSource=""{Binding DataListViewModel}"" />
</TabItem>
</TabControl>
</StackPanel>
</Window>";
[STAThread]
static void Main()
{
var window = Xaml.LoadXaml<Window>(xaml);
window.DataContext = new MainWindowViewModel();
window.ShowDialog();
}
}
public class MainWindowViewModel : ViewModel
{
public MainWindowViewModel()
{
TabItemViewModel = new TabItemViewModel();
UpdateCommand = new Command(Update);
}
public TabItemViewModel TabItemViewModel { get; set; }
public ICommand UpdateCommand { get; set; }
public void Update()
{
TabItemViewModel.Update();
}
}
public class TabItemViewModel : ViewModel
{
public ObservableCollection<DataViewModel> DataListViewModel { get; set; } =
new ObservableCollection<DataViewModel>();
public TabItemViewModel()
{
Update();
}
public void Update()
{
DataListViewModel = new ObservableCollection<DataViewModel>();
DataListViewModel.Add( new DataViewModel() { Name = "data" });
OnPropertyChanged(nameof(DataListViewModel));
}
}
public class ViewModel : INotifyPropertyChanged
{
public event PropertyChangedEventHandler PropertyChanged;
protected virtual void OnPropertyChanged([CallerMemberName] string propertyName = null)
{
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
}
}
#region MVVM
public class DataViewModel : ViewModel
{
private string name;
public string Name
{
get { return name; }
set
{
if (name != value)
{
name = value;
OnPropertyChanged(nameof(this.Name));
}
}
}
}
public class Command : ICommand
{
private readonly Action action;
public Command(Action action)
{
this.action = action;
}
public bool CanExecute(object parameter)
{
return true;
}
public void Execute(object parameter)
{
action();
}
public event EventHandler CanExecuteChanged;
}
#endregion
public class Xaml
{
public static T LoadXaml<T>(string xaml)
{
using (var stringReader = new System.IO.StringReader(xaml))
using (var xmlReader = System.Xml.XmlReader.Create(stringReader))
return (T)System.Windows.Markup.XamlReader.Load(xmlReader);
}
}
}
答: 暂无答案
评论