WPF Error: Recursive call to Automation Peer API is not valid
WPF Error: Recursive call to Automation Peer API is not valid
我们已经使用 WPF Toolkit DataGrid 和 .NET 4.0 大约 1.5 年了。有时我们会遇到异常 - "Recursive call to Automation Peer API is not valid" 在一些客户端 PC 上,其他用户没有这个问题。
我们使用了 WPF Toolkit DataGrid with Template Column,其中单元格模板有一个复选框(WPF Toolkit DataGrid 作为 CheckBox 内容控件)。我们还使用了此网格中的上下文菜单。
Type : System.InvalidOperationException, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
Message : Recursive call to Automation Peer API is not valid.
Source : PresentationCore
Help link :
Data : System.Collections.ListDictionaryInternal
TargetSite : System.Collections.Generic.List`1[System.Windows.Automation.Peers.AutomationPeer] GetChildren()
HResult : -2146233079
Stack Trace : at System.Windows.Automation.Peers.AutomationPeer.GetChildren()
at System.Windows.Automation.Peers.AutomationPeer.isDescendantOf(AutomationPeer parent)
at System.Windows.Automation.Peers.AutomationPeer.isDescendantOf(AutomationPeer parent)
at System.Windows.Automation.Peers.AutomationPeer.isDescendantOf(AutomationPeer parent)
at System.Windows.Automation.Peers.AutomationPeer.isDescendantOf(AutomationPeer parent)
at System.Windows.Automation.Peers.AutomationPeer.isDescendantOf(AutomationPeer parent)
at System.Windows.Automation.Peers.AutomationPeer.isDescendantOf(AutomationPeer parent)
at System.Windows.Automation.Peers.AutomationPeer.isDescendantOf(AutomationPeer parent)
at System.Windows.Automation.Peers.AutomationPeer.isDescendantOf(AutomationPeer parent)
at System.Windows.Automation.Peers.AutomationPeer.isDescendantOf(AutomationPeer parent)
at System.Windows.Automation.Peers.AutomationPeer.ValidateConnected(AutomationPeer connectedPeer)
at MS.Internal.Automation.ElementProxy.StaticWrap(AutomationPeer peer, AutomationPeer referencePeer)
at System.Windows.Automation.Peers.AutomationPeer.UpdateChildrenInternal(Int32 invalidateLimit)
at System.Windows.Automation.Peers.AutomationPeer.UpdateChildren()
at System.Windows.Automation.Peers.AutomationPeer.ResetChildrenCache()
at Microsoft.Windows.Automation.Peers.DataGridItemAutomationPeer.GetChildrenCore()
at System.Windows.Automation.Peers.AutomationPeer.EnsureChildren()
at System.Windows.Automation.Peers.AutomationPeer.GetChildren()
at System.Windows.Automation.Peers.AutomationPeer.isDescendantOf(AutomationPeer parent)
at System.Windows.Automation.Peers.AutomationPeer.isDescendantOf(AutomationPeer parent)
at System.Windows.Automation.Peers.AutomationPeer.isDescendantOf(AutomationPeer parent)
at System.Windows.Automation.Peers.AutomationPeer.isDescendantOf(AutomationPeer parent)
at System.Windows.Automation.Peers.AutomationPeer.isDescendantOf(AutomationPeer parent)
at System.Windows.Automation.Peers.AutomationPeer.isDescendantOf(AutomationPeer parent)
at System.Windows.Automation.Peers.AutomationPeer.isDescendantOf(AutomationPeer parent)
at System.Windows.Automation.Peers.AutomationPeer.isDescendantOf(AutomationPeer parent)
at System.Windows.Automation.Peers.AutomationPeer.isDescendantOf(AutomationPeer parent)
at System.Windows.Automation.Peers.AutomationPeer.ValidateConnected(AutomationPeer connectedPeer)
at System.Windows.Automation.Peers.AutomationPeer.AutomationPeerFromInputElement(IInputElement focusedElement)
at System.Windows.Automation.Peers.AutomationPeer.RaiseFocusChangedEventHelper(IInputElement newFocus)
at System.Windows.Input.KeyboardDevice.ChangeFocus(DependencyObject focus, Int32 timestamp)
at System.Windows.Input.KeyboardDevice.TryChangeFocus(DependencyObject newFocus, IKeyboardInputProvider keyboardInputProvider, Boolean askOld, Boolean askNew, Boolean forceToNullIfFailed)
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.Interop.HwndKeyboardInputProvider.OnSetFocus(IntPtr hwnd)
at System.Windows.Interop.HwndKeyboardInputProvider.FilterMessage(IntPtr hwnd, WindowMessage message, 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)
如果我们做错了什么,请告诉我们解决方案或建议。
on Whosebug之前有人问过这个问题,但一直没有解决。
当我查看代码时,看起来它是由某些可能正在修改集合的东西引起的,因为正在枚举集合,从而强制进行新的枚举,而原始枚举已经发生。这是由于自动化对等代码中的框架级保护。
除非您包含在修改集合时记录日志的代码并设法成功调试它,否则尝试找出它发生的方式和原因可能非常棘手。一种解决方案可能是确保所有集合修改仅发生在 GUI 线程上,但如果数量很大,这可能会导致 UI 阻塞。
然而,这一切都只是猜测。就个人而言,我从来没有在我拥有的任何代码中使用过它,所以如果您有可以成功重现它的示例代码,我很乐意尝试看看。
潜在修复
我忘了提及有些人建议可能的解决方法是通过添加以下内容来覆盖模板:
protected override System.Windows.Automation.Peers.AutomationPeer OnCreateAutomationPeer()
{
// Create your own AutomationPeer
// return new MyAutomationPeer(this);
// or return null if you don't need it
return null;
}
我不知道这有多有效,以及它是否删除了任何功能,因为它基本上是在说你没有对等体。
(看这个MSDN Forum post)
我已经使用低版本的WPFToolkit解决了这个问题。早些时候我使用的是导致问题的 WPFToolkit v3.5.50211.1。现在我正在使用低版本v3.5.40619.1来解决这个问题。
在 WPFToolkit v3.5.50211.1 中修复了一个与 UI Automation 相关的错误,我猜是因为这个自动化对等问题在使用最新的 WPFtoolkit 时出现。
查看相关链接-
WPF Recursive call to Automation Peer API is not valid
我们已经使用 WPF Toolkit DataGrid 和 .NET 4.0 大约 1.5 年了。有时我们会遇到异常 - "Recursive call to Automation Peer API is not valid" 在一些客户端 PC 上,其他用户没有这个问题。
我们使用了 WPF Toolkit DataGrid with Template Column,其中单元格模板有一个复选框(WPF Toolkit DataGrid 作为 CheckBox 内容控件)。我们还使用了此网格中的上下文菜单。
Type : System.InvalidOperationException, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
Message : Recursive call to Automation Peer API is not valid.
Source : PresentationCore
Help link :
Data : System.Collections.ListDictionaryInternal
TargetSite : System.Collections.Generic.List`1[System.Windows.Automation.Peers.AutomationPeer] GetChildren()
HResult : -2146233079
Stack Trace : at System.Windows.Automation.Peers.AutomationPeer.GetChildren()
at System.Windows.Automation.Peers.AutomationPeer.isDescendantOf(AutomationPeer parent)
at System.Windows.Automation.Peers.AutomationPeer.isDescendantOf(AutomationPeer parent)
at System.Windows.Automation.Peers.AutomationPeer.isDescendantOf(AutomationPeer parent)
at System.Windows.Automation.Peers.AutomationPeer.isDescendantOf(AutomationPeer parent)
at System.Windows.Automation.Peers.AutomationPeer.isDescendantOf(AutomationPeer parent)
at System.Windows.Automation.Peers.AutomationPeer.isDescendantOf(AutomationPeer parent)
at System.Windows.Automation.Peers.AutomationPeer.isDescendantOf(AutomationPeer parent)
at System.Windows.Automation.Peers.AutomationPeer.isDescendantOf(AutomationPeer parent)
at System.Windows.Automation.Peers.AutomationPeer.isDescendantOf(AutomationPeer parent)
at System.Windows.Automation.Peers.AutomationPeer.ValidateConnected(AutomationPeer connectedPeer)
at MS.Internal.Automation.ElementProxy.StaticWrap(AutomationPeer peer, AutomationPeer referencePeer)
at System.Windows.Automation.Peers.AutomationPeer.UpdateChildrenInternal(Int32 invalidateLimit)
at System.Windows.Automation.Peers.AutomationPeer.UpdateChildren()
at System.Windows.Automation.Peers.AutomationPeer.ResetChildrenCache()
at Microsoft.Windows.Automation.Peers.DataGridItemAutomationPeer.GetChildrenCore()
at System.Windows.Automation.Peers.AutomationPeer.EnsureChildren()
at System.Windows.Automation.Peers.AutomationPeer.GetChildren()
at System.Windows.Automation.Peers.AutomationPeer.isDescendantOf(AutomationPeer parent)
at System.Windows.Automation.Peers.AutomationPeer.isDescendantOf(AutomationPeer parent)
at System.Windows.Automation.Peers.AutomationPeer.isDescendantOf(AutomationPeer parent)
at System.Windows.Automation.Peers.AutomationPeer.isDescendantOf(AutomationPeer parent)
at System.Windows.Automation.Peers.AutomationPeer.isDescendantOf(AutomationPeer parent)
at System.Windows.Automation.Peers.AutomationPeer.isDescendantOf(AutomationPeer parent)
at System.Windows.Automation.Peers.AutomationPeer.isDescendantOf(AutomationPeer parent)
at System.Windows.Automation.Peers.AutomationPeer.isDescendantOf(AutomationPeer parent)
at System.Windows.Automation.Peers.AutomationPeer.isDescendantOf(AutomationPeer parent)
at System.Windows.Automation.Peers.AutomationPeer.ValidateConnected(AutomationPeer connectedPeer)
at System.Windows.Automation.Peers.AutomationPeer.AutomationPeerFromInputElement(IInputElement focusedElement)
at System.Windows.Automation.Peers.AutomationPeer.RaiseFocusChangedEventHelper(IInputElement newFocus)
at System.Windows.Input.KeyboardDevice.ChangeFocus(DependencyObject focus, Int32 timestamp)
at System.Windows.Input.KeyboardDevice.TryChangeFocus(DependencyObject newFocus, IKeyboardInputProvider keyboardInputProvider, Boolean askOld, Boolean askNew, Boolean forceToNullIfFailed)
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.Interop.HwndKeyboardInputProvider.OnSetFocus(IntPtr hwnd)
at System.Windows.Interop.HwndKeyboardInputProvider.FilterMessage(IntPtr hwnd, WindowMessage message, 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)
如果我们做错了什么,请告诉我们解决方案或建议。
on Whosebug之前有人问过这个问题,但一直没有解决。
当我查看代码时,看起来它是由某些可能正在修改集合的东西引起的,因为正在枚举集合,从而强制进行新的枚举,而原始枚举已经发生。这是由于自动化对等代码中的框架级保护。
除非您包含在修改集合时记录日志的代码并设法成功调试它,否则尝试找出它发生的方式和原因可能非常棘手。一种解决方案可能是确保所有集合修改仅发生在 GUI 线程上,但如果数量很大,这可能会导致 UI 阻塞。
然而,这一切都只是猜测。就个人而言,我从来没有在我拥有的任何代码中使用过它,所以如果您有可以成功重现它的示例代码,我很乐意尝试看看。
潜在修复
我忘了提及有些人建议可能的解决方法是通过添加以下内容来覆盖模板:
protected override System.Windows.Automation.Peers.AutomationPeer OnCreateAutomationPeer()
{
// Create your own AutomationPeer
// return new MyAutomationPeer(this);
// or return null if you don't need it
return null;
}
我不知道这有多有效,以及它是否删除了任何功能,因为它基本上是在说你没有对等体。
(看这个MSDN Forum post)
我已经使用低版本的WPFToolkit解决了这个问题。早些时候我使用的是导致问题的 WPFToolkit v3.5.50211.1。现在我正在使用低版本v3.5.40619.1来解决这个问题。
在 WPFToolkit v3.5.50211.1 中修复了一个与 UI Automation 相关的错误,我猜是因为这个自动化对等问题在使用最新的 WPFtoolkit 时出现。
查看相关链接-
WPF Recursive call to Automation Peer API is not valid