wpf 来自 PresentationFramework.dll 的 NullReferenceException

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/16245732/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-13 08:42:00  来源:igfitidea点击:

NullReferenceException from PresentationFramework.dll

wpfwindows-8datagrid

提问by Mike Dinescu

I'm fighting with a strange NullReferenceException that is apparently fired from the GetNameCore()function of the ItemAutomationPeerclass.

我正在处理一个奇怪的 NullReferenceException,它显然是从ItemAutomationPeer类的GetNameCore()函数触发的

The details of the exception are below but the really intriguing aspect is that it doesn't occur on my development machine running Windows 7, or other Windows 7 computers we have tested with. It only happens on my Windows 8 Pro test machine.

异常的详细信息如下,但真正有趣的方面是它不会发生在我运行 Windows 7 的开发机器或我们测试过的其他 Windows 7 计算机上。它只发生在我的 Windows 8 Pro 测试机上。

The exception is thrown apparently when attempting to edit a cell in a WPF DataGrid control.

尝试编辑 WPF DataGrid 控件中的单元格时显然会引发异常。

I've been trying to track it down all day without success. I tried debugging the process remotely using Visual Studio and stepping through the code but none of the user code seems to be triggering the exception. It's obviously executed by a sequence of events inside of the PresentationFramework.Dll and the exception just bubbles up through the AppDomain and eventually crashes the application.

我一整天都在试图追踪它,但没有成功。我尝试使用 Visual Studio 远程调试该过程并逐步执行代码,但似乎没有任何用户代码触发异常。它显然是由 PresentationFramework.Dll 内的一系列事件执行的,异常只是通过 AppDomain 冒泡并最终使应用程序崩溃。

If anybody can think of anything that might be causing this, or a way to fix it it would really help.

如果有人能想到可能导致这种情况的任何事情,或解决它的方法,那真的会有所帮助。

Exception Type:         System.NullReferenceException
Exception Message:  Object reference not set to an instance of an object.
Method Information: System.String GetNameCore()
Exception Source:   PresentationFramework

Stack Trace
  at System.Windows.Automation.Peers.ItemAutomationPeer.GetNameCore()
  at System.Windows.Automation.Peers.AutomationPeer.UpdateSubtree()
  at System.Windows.Automation.Peers.AutomationPeer.UpdateSubtree()
  at System.Windows.Automation.Peers.AutomationPeer.UpdateSubtree()
  at System.Windows.ContextLayoutManager.fireAutomationEvents()
  at System.Windows.ContextLayoutManager.UpdateLayout()
  at System.Windows.ContextLayoutManager.UpdateLayoutCallback(Object arg)
  at System.Windows.Media.MediaContext.InvokeOnRenderCallback.DoWork()
  at System.Windows.Media.MediaContext.FireInvokeOnRenderCallbacks()
  at System.Windows.Media.MediaContext.RenderMessageHandlerCore(Object    resizedCompositionTarget)
  at System.Windows.Media.MediaContext.AnimatedRenderMessageHandler(Object resizedCompositionTarget)
  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.DispatcherOperation.InvokeImpl()
  at System.Windows.Threading.DispatcherOperation.InvokeInSecurityContext(Object state)
  at System.Threading.ExecutionContext.RunInternal(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean preserveSyncCtx)
  at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean preserveSyncCtx)
  at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state)
  at System.Windows.Threading.DispatcherOperation.Invoke()
  at System.Windows.Threading.Dispatcher.ProcessQueue()
  at System.Windows.Threading.Dispatcher.WndProcHook(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.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(Window window)
  at System.Windows.Application.Run()

回答by Mike Dinescu

After a lot of back-and-forth with the remote debugger, and nearly fruitless searches online I was able to track down the issue to a couple of miss-behaving ItemAutomationPeerinstances.

在使用远程调试器进行了大量来回调试以及几乎毫无结果的在线搜索之后,我能够将问题追溯到几个行为不端的 ItemAutomationPeer实例。

When I ran into this issue I had zero knowledge about UI Automationand how it is supported in the WPF framework. In fact, when AutomationPeerhad me thinking of COM interop for some reason so I chased the wrong issue for a while. If you are reading this and don't know what UI Automation is perhaps starting hereand heremight give you an idea as far as what UI Automation means in the context of WPF.

当我遇到这个问题时,我对UI 自动化以及 WPF 框架如何支持它的了解为零。事实上,当AutomationPeer出于某种原因让我考虑 COM 互操作时,所以我追了一段时间错误的问题。如果您正在阅读本文并且不知道 UI 自动化可能从这里开始,这里可能会让您了解 UI 自动化在 WPF 上下文中的含义。

In my case, it turns out that the reason why the application was crashing on the Windows 8 test machine yet it was working fine on my development machine (and countless other computers that it had been deployed to) was that the Windows 8 machine had some sort of UI accessibility application (or some other UI Automation client) running. As soon as I started the Narrator application on my Windows 7 development machine I was able to get the app to crash just the same..

就我而言,结果证明应用程序在 Windows 8 测试机器上崩溃但在我的开发机器(以及它已部署到的无数其他计算机)上运行良好的原因是 Windows 8 机器有一些正在运行的某种 UI 辅助功能应用程序(或其他一些 UI 自动化客户端)。一旦我在我的 Windows 7 开发机器上启动讲述人应用程序,我就能够让应用程序崩溃。

Once I understood the root problem, I still was unable to further debug this to find out exactly which control was causing the problem but more reading online seemed to point in the general direction of custom controls and so I started a process of elimination to determine which custom WPF controls were guilty. I found two custom controls - one that extended a DataGrid, and another that extended a ListBox.

一旦我理解了根本问题,我仍然无法进一步调试以找出导致问题的确切控件,但更多的在线阅读似乎指向自定义控件的大方向,因此我开始了一个消除过程以确定哪个控件自定义 WPF 控件是有罪的。我找到了两个自定义控件 - 一个扩展了 DataGrid,另一个扩展了 ListBox。

Finally, the solution to the problem in my case was to create custom classes that extend the ItemsControlAutomationPeerbase class and to provide those as automation peers on each of the custom controls that had issues by overriding the OnCreateAutomationPeermethod.

最后,在我的案例中,问题的解决方案是创建扩展ItemsControlAutomationPeer基类的自定义类,并通过覆盖OnCreateAutomationPeer方法在每个有问题的自定义控件上提供这些自定义类作为自动化对等项

protected override AutomationPeer OnCreateAutomationPeer()
{
    return new ControlSpecificCustomAutomationPeer(this);
}

Where the ControlSpecificCustomAutomationPeer class might looks something like this at the very least:

ControlSpecificCustomAutomationPeer 类至少看起来像这样:

public class ControlSpecificCustomAutomationPeer
    : ItemsControlAutomationPeer
{
    public ControlSpecificCustomAutomationPeer(ItemsControl owner)
        : base(owner)
    {
    }

    protected override string GetNameCore()
    {
        return "";                         // return something meaningful here..
    }

    protected override ItemAutomationPeer CreateItemAutomationPeer(object item)
    {
        return new CustomDummyItemAutomationPeer(item, this);
    }             
}

public class CustomDummyItemAutomationPeer
    : System.Windows.Automation.Peers.ItemAutomationPeer
{
    public CustomDummyItemAutomationPeer(object item, ItemsControlAutomationPeer itemsControlAutomationPeer)
        : base(item, itemsControlAutomationPeer)
    {
    }

    protected override string GetNameCore()
    {
        if (Item == null)
            return "";            

        return Item.ToString() ?? "";
    }

    protected override AutomationControlType GetAutomationControlTypeCore()
    {
        return System.Windows.Automation.Peers.AutomationControlType.Text;
    }

    protected override string GetClassNameCore()
    {
        return "Dummy";
    }
}

回答by Neil B

I chose to catch the error and handle it as a 'non-fatal' error.

我选择捕获错误并将其作为“非致命”错误进行处理。

private void App_DispatcherUnhandledException(object sender, System.Windows.Threading.DispatcherUnhandledExceptionEventArgs e)
{
    if (e.Exception.Source?.ToString() == "PresentationFramework")
    {
        e.Handled = true;
        Postgres.LogException(e.Exception, false);
        return;
    }

    HandleException(e.Exception);
    e.Handled = true;
    Shutdown();
}

回答by Patrick Kursawe

回答by gusmally supports Monica

This issue for me was reliably reproducible with turning on Narrator and scrolling in a treeview that was using virtualisation with VirtualizationMode set to Recycling. Setting it to Standard led to a very slight performance hit, but the crash no longer occurs.

通过打开讲述人并在使用虚拟化并将 VirtualizationMode 设置为 Recycling 的树视图中滚动,我可以可靠地重现这个问题。将其设置为 Standard 会导致非常轻微的性能损失,但不再发生崩溃。