There is an apparent bug in the Chart control which is causing our application to crash when browsing through top-level tabs. Given the following XAML (no C# partial class required and dramatically simplified from the actual application code):
<Window xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:my="clr-namespace:ChartFX.WPF;assembly=ChartFX.WPF" Width="800" Height="600"> <TabControl> <TabItem Header="OuterTab#1"/> <TabItem Header="OuterTab#2"> <TabControl> <TabItem Header="InnerTab#1"/> <TabItem Header="InnerTab#2"> <my:Chart/> </TabItem> </TabControl> </TabItem> </TabControl> </Window>
As you can see above, we have a TabControl nested inside another TabControl. The Chart is on a TabItem in the inner TabControl. If you click on OuterTab#2 followed by InnerTab#2 (thus displaying the Chart) and then click back to OuterTab#1, everything is fine. If however you click on OuterTab#2 and then OuterTab#1 (thus NOT displaying the chart), the Chart throws a NullReferenceException:
at ChartFX.WPF.Chart.b(Object A_0, RoutedEventArgs A_1) at System.Windows.RoutedEventHandlerInfo.InvokeHandler(Object target, RoutedEventArgs routedEventArgs) at System.Windows.EventRoute.InvokeHandlersImpl(Object source, RoutedEventArgs args, Boolean reRaised) at System.Windows.UIElement.RaiseEventImpl(DependencyObject sender, RoutedEventArgs args) at System.Windows.UIElement.RaiseEvent(RoutedEventArgs e) at System.Windows.BroadcastEventHelper.BroadcastEvent(DependencyObject root, RoutedEvent routedEvent) at System.Windows.BroadcastEventHelper.BroadcastUnloadedEvent(Object root) at MS.Internal.LoadedOrUnloadedOperation.DoWork() at System.Windows.Media.MediaContext.FireLoadedPendingCallbacks() at System.Windows.Media.MediaContext.FireInvokeOnRenderCallbacks() at System.Windows.Media.MediaContext.RenderMessageHandlerCore(Object resizedCompositionTarget) at System.Windows.Media.MediaContext.RenderMessageHandler(Object resizedCompositionTarget) at System.Windows.Threading.ExceptionWrapper.InternalRealCall(Delegate callback, Object args, Boolean isSingleParameter) at System.Windows.Threading.ExceptionWrapper.TryCatchWhen(Object source, Delegate callback, Object args, Boolean isSingleParameter, Delegate catchHandler) at System.Windows.Threading.Dispatcher.WrappedInvoke(Delegate callback, Object args, Boolean isSingleParameter, Delegate catchHandler) at System.Windows.Threading.DispatcherOperation.InvokeImpl() at System.Windows.Threading.DispatcherOperation.InvokeInSecurityContext(Object state) at System.Threading.ExecutionContext.runTryCode(Object userData) at System.Runtime.CompilerServices.RuntimeHelpers.ExecuteCodeWithGuaranteedCleanup(TryCode code, CleanupCode backoutCode, Object userData) at System.Threading.ExecutionContext.RunInternal(ExecutionContext executionContext, ContextCallback callback, Object state) 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, Boolean isSingleParameter) at System.Windows.Threading.ExceptionWrapper.TryCatchWhen(Object source, Delegate callback, Object args, Boolean isSingleParameter, Delegate catchHandler) at System.Windows.Threading.Dispatcher.WrappedInvoke(Delegate callback, Object args, Boolean isSingleParameter, Delegate catchHandler) at System.Windows.Threading.Dispatcher.InvokeImpl(DispatcherPriority priority, TimeSpan timeout, Delegate method, Object args, Boolean isSingleParameter) at System.Windows.Threading.Dispatcher.Invoke(DispatcherPriority priority, Delegate method, Object arg) 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() at longrangemodel.ui.App.Main() in C:\Users\James\Desktop\longrangemodel.ui\obj\Debug\App.g.cs:line 0
Interestingly, the following sequence does NOT cause any exceptions to be thrown:
Click on OuterTab#2
Click InnerTab#2 (thus displaying the Chart).
Click InnerTab#1 (thus hiding the Chart).
You can now click back and forth between OuterTab#1 and OuterTab#2 without revealing the Chart again and never throwing the NullReferenceException.
I've tried a variety of workarounds without success such as hiding, collapsing, and disabling combinations of InnerTab#2 and the Chart control. A workaround or fix (or an explanation of what I'm doing wrong if that's the case) would be much appreciated. Thanks in advance for investigating this problem.