PresentationFramework.dll的NullReferenceException

Mik*_*scu 13 wpf datagrid windows-8

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

下面的例外细节如下,但真正有趣的方面是它不会出现在运行Windows 7的开发机器或我们测试过的其他Windows 7计算机上.它只发生在我的Windows 8 Pro测试机上.

尝试编辑WPF DataGrid控件中的单元格时,显然会抛出异常.

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

如果任何人可以想到任何可能导致这种情况的事情,或者某种方法来解决它,那将非常有帮助.

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()
Run Code Online (Sandbox Code Playgroud)

Mik*_*scu 14

经过远程调试器的大量反复,以及几乎无效的在线搜索后,我能够将问题追溯到几个行为不端的ItemAutomationPeer实例.

当我遇到这个问题时,我对UI自动化及其在WPF框架中的支持方面缺乏了解.实际上,当AutomationPeer由于某种原因让我想到COM互操作时,我一时间追错了问题.如果您正在阅读本文并且不知道UI Automation可能从这里开始,这里可能会让您了解UI自动化在WPF上下文中的含义.

在我的情况下,事实证明应用程序崩溃在Windows 8测试机器上但它在我的开发机器(以及它已被部署到的无数其他计算机上)正常工作的原因是Windows 8机器有一些运行的UI辅助功能应用程序(或其他一些UI自动化客户端).一旦我在Windows 7开发机器上启动了Narrator应用程序,我就能让应用程序崩溃一样.

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

最后,我的问题的解决方案是创建自定义类,扩展ItemsControlAutomationPeer基类,并通过覆盖OnCreateAutomationPeer方法在每个自定义控件上提供这些自定义控件.

protected override AutomationPeer OnCreateAutomationPeer()
{
    return new ControlSpecificCustomAutomationPeer(this);
}
Run Code Online (Sandbox Code Playgroud)

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";
    }
}
Run Code Online (Sandbox Code Playgroud)

  • 无论如何,我们遇到了同样的问题,但只有当应用程序在 Win8 上运行时或者我们在 Win7 中打开讲述人时。事实证明,我们的交互是各种属性设置者之间难以调试的交互。设置属性后,我们在代码中的某个位置将其设置回 null。在我诊断之前,我发现上述解决方案“修复”了自动化对等症状。 (2认同)