WPF DataGrid没有退出编辑模式

时间:2022-03-22 22:17:01

I have a DataGrid displaying several rows and columns of data, each is bound to its own Property. The DataGrid is NOT on a TabControl but whenever the window that it lives on is closed and reopened I get the error message: 'DeferRefresh' is not allowed during an AddNew or EditItem transaction. ONLY IF there were validations issues with one or more of the DataGrid's cells.

我有一个DataGrid显示几个行和列的数据,每个都绑定到自己的属性。 DataGrid不在TabControl上,但每当它所在的窗口关闭并重新打开时,我都会收到错误消息:在AddNew或EditItem事务期间不允许使用'DeferRefresh'。只有在一个或多个DataGrid单元格存在验证问题时才会出现问题。

For example: The property bound to the DataGrid's cell is a double and the user enters "hello", of course then WPF's automatic red border is displayed around the cell. Now, if the user were to close the window, and reopen it the error would occur.

例如:绑定到DataGrid单元格的属性是double,用户输入“hello”,当然然后WPF的自动红色边框显示在单元格周围。现在,如果用户要关闭窗口,并重新打开它,则会发生错误。

I know why the error is being thrown, because the cell is not leaving "edit mode".

我知道为什么错误被抛出,因为单元格没有离开“编辑模式”。

How can I resolve this error?

我该如何解决这个错误?

Other Notes:

  • I have looked at this question but that is pertaining to a DataGrid on a TabControl (which mine is not).
  • 我看过这个问题,但这与TabControl上的DataGrid有关(我的不是)。

  • I have attempted to limit the user's input so that if the Cell requires a double or then only accept a double, but the problem is there are no good ways to limit the number of decimal points (".") that the user can insert. I am controlling user input through PreviewTextInput and only allowing 0-9 and ".".
  • 我试图限制用户的输入,以便如果Cell需要一个double或者只接受一个double,但问题是没有好的方法来限制用户可以插入的小数点(“。”)。我通过PreviewTextInput控制用户输入,只允许0-9和“。”。


Exception Detail (if this helps)

异常细节(如果这有帮助)

System.InvalidOperationException was unhandled
  Message='DeferRefresh' is not allowed during an AddNew or EditItem transaction.
  Source=PresentationFramework
  StackTrace:
       at System.Windows.Data.CollectionView.DeferRefresh()
       at System.Windows.Controls.ItemCollection.SetCollectionView(CollectionView view)
       at System.Windows.Controls.ItemsControl.OnItemsSourceChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
       at System.Windows.DependencyObject.OnPropertyChanged(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.Data.BindingExpressionBase.Invalidate(Boolean isASubPropertyChange)
       at System.Windows.Data.BindingExpression.TransferValue(Object newValue, Boolean isASubPropertyChange)
       at System.Windows.Data.BindingExpression.Activate(Object item)
       at System.Windows.Data.BindingExpression.AttachToContext(AttachAttempt attempt)
       at System.Windows.Data.BindingExpression.MS.Internal.Data.IDataBindEngineClient.AttachToContext(Boolean lastChance)
       at MS.Internal.Data.DataBindEngine.Task.Run(Boolean lastChance)
       at MS.Internal.Data.DataBindEngine.Run(Object arg)
       at MS.Internal.Data.DataBindEngine.OnLayoutUpdated(Object sender, EventArgs e)
       at System.Windows.ContextLayoutManager.fireLayoutUpdateEvent()
       at System.Windows.ContextLayoutManager.UpdateLayout()
       at System.Windows.Interop.HwndSource.SetLayoutSize()
       at System.Windows.Interop.HwndSource.set_RootVisualInternal(Visual value)
       at System.Windows.Window.SetRootVisualAndUpdateSTC()
       at System.Windows.Window.SetupInitialState(Double requestedTop, Double requestedLeft, Double requestedWidth, Double requestedHeight)
       at System.Windows.Window.CreateSourceWindow(Boolean duringShow)
       at System.Windows.Window.ShowHelper(Object booleanBox)
       at REACT.ViewModel.ReceiverListViewModel.ShowWindow(String name) in C:\Users\jcarroll42\Documents\Sandbox\REACT\SW\Source\ViewModel\ReceiverListViewModel.cs:line 238
       at REACT.Commands.ShowWindowCommand.Execute(Object parameter) in C:\Users\jcarroll42\Documents\Sandbox\REACT\SW\Source\Commands.cs:line 137
       at MS.Internal.Commands.CommandHelpers.CriticalExecuteCommandSource(ICommandSource commandSource, Boolean userInitiated)
       at System.Windows.Controls.Button.OnClick()
       at System.Windows.Controls.Primitives.ButtonBase.OnMouseLeftButtonUp(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)
       at System.Windows.Threading.Dispatcher.WrappedInvoke(Delegate callback, Object args, Int32 numArgs, Delegate catchHandler)
       at System.Windows.Threading.Dispatcher.InvokeImpl(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.Application.RunInternal(Window window)
       at System.Windows.Application.Run()
       at REACT.App.Main() in C:\Users\jcarroll42\Documents\Sandbox\REACT\SW\Source\obj\x86\Debug\App.g.cs:line 0
       at System.AppDomain._nExecuteAssembly(RuntimeAssembly assembly, String[] args)
       at Microsoft.VisualStudio.HostingProcess.HostProc.RunUsersAssembly()
       at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean ignoreSyncCtx)
       at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state)
       at System.Threading.ThreadHelper.ThreadStart()
  InnerException: 

I'll be happy to provide anymore information if needed.

如果需要,我很乐意提供更多信息。

2 个解决方案

#1


9  

You can try to force datagrid into cancelling edition when you need it:

您可以在需要时尝试强制datagrid取消版本:

myDatagrid.CommitEdit(); 
myDatagrid.CancelEdit();

This worked for me, i had a similar issue when reordering rows.

这对我有用,我在重新排序行时遇到了类似的问题。

#2


5  

This is a bug that was fixed with .NET Framework 4.5+. Unfortunately, for those of us stuck with previous versions the error is still a problem. The best solution I have found is to simply bind the DataGrid to properties with type string. That way, full control over user input is available. With full control, the user should not be able to trigger any errors, and theDataGrid will not crash the program.

这是使用.NET Framework 4.5+修复的错误。不幸的是,对于我们这些坚持以前版本的人来说,错误仍然是一个问题。我发现的最佳解决方案是简单地将DataGrid绑定到类型为string的属性。这样,就可以完全控制用户输入。通过完全控制,用户不应该能够触发任何错误,并且DataGrid不会使程序崩溃。

#1


9  

You can try to force datagrid into cancelling edition when you need it:

您可以在需要时尝试强制datagrid取消版本:

myDatagrid.CommitEdit(); 
myDatagrid.CancelEdit();

This worked for me, i had a similar issue when reordering rows.

这对我有用,我在重新排序行时遇到了类似的问题。

#2


5  

This is a bug that was fixed with .NET Framework 4.5+. Unfortunately, for those of us stuck with previous versions the error is still a problem. The best solution I have found is to simply bind the DataGrid to properties with type string. That way, full control over user input is available. With full control, the user should not be able to trigger any errors, and theDataGrid will not crash the program.

这是使用.NET Framework 4.5+修复的错误。不幸的是,对于我们这些坚持以前版本的人来说,错误仍然是一个问题。我发现的最佳解决方案是简单地将DataGrid绑定到类型为string的属性。这样,就可以完全控制用户输入。通过完全控制,用户不应该能够触发任何错误,并且DataGrid不会使程序崩溃。