NullReferenceException from PresentationFramework.dll
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.
FYI, this bug will be fixed in a future release of .Net 4.8. https://developercommunity.visualstudio.com/content/problem/575165/vs-1604-ide-crash-argumentnullexception.html
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();
}
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 ItemAutomationPeer instances.
When I ran into this issue I had zero knowledge about UI Automation and how it is supported in the WPF framework. In fact, when AutomationPeer had 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 here and here might give you an idea as far as what UI Automation means in the context of 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..
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.
Finally, the solution to the problem in my case was to create custom classes that extend the ItemsControlAutomationPeer base class and to provide those as automation peers on each of the custom controls that had issues by overriding the OnCreateAutomationPeer method.
protected override AutomationPeer OnCreateAutomationPeer()
{
return new ControlSpecificCustomAutomationPeer(this);
}
Where the ControlSpecificCustomAutomationPeer class might looks something like this at the very least:
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";
}
}