views:

389

answers:

1

As part of learning wpf I'm working through some MS 'lab' sample apps; The finished exercise looks right, but I'm hitting a NullReferenceException with "Source code unavailable" issue (exception detail below). It appears to be thrown after the main window is shown.

I suspect the issue is in the XAML, but the debugger isn't helping me as much as I'd like. I've put break points everywhere the NavigationService is called in code, and none are being hit before the exception occurs. The type that the page function(s) returns was changed from string to object as part of the exercise.

In a real project. there would likely be enough unit tests and checks in place to not get in this state, but as long as I am and as part of the exercise of learning wpf, it surely can't hurt to know how to debug better!

How can I debug something like this better?

<--- EDITED COMMENTS

@electronherder

The closest guess I can make is that there is a Frame in Window1 that is not hooked up correctly. The idea is that the Frame displays contact information about the currently selected contact in a ListBox; this is done in code as follows:

void ListItemSelected(object sender, SelectionChangedEventArgs args) {
        // show first page function on the right hand side frame
        var pageFunction = new ContactDetailPage1(false, lstBoxAllContacts.SelectedIndex);
        pageFunction.Return += pageFunction0_Return;
        Frame_RightPane.Navigate(pageFunction);

        //update status bar
        if (lstBoxAllContacts.SelectedItem != null) {
            var contact = lstBoxAllContacts.SelectedItem as Contact;
            statusBar.Text = contact.FirstName + " " + contact.LastName;
        }
        else {
            statusBar.Text = "No contacts on file.";
        }
    }

Before Window1 exits the call to Show(), this method executes without crashing. It does have that call to do some navigation, which I do not fully understand but is copied from the lab exercise notes. The navigation is related to a different window called ContactDetailPage1, and here's how the lab notes explain things:

"We want to be able to display this page in two modes: Read and Edit. That way we can reuse the Read mode in the contact details frame, Frame_RightPane."

The event hookup (pageFunction.Return += pageFunction0_Return;) is also a bit suspect, since it is intentionally a no-op to keep the compiler happy. I put an assert inside it though, as you can see in the code below:

    // This is the ContactDetailPage1 page function's return handler; merely a placeholder 
    // since the page is displayed in read mode and doesn't return anything.
    private static void pageFunction0_Return(object sender, ReturnEventArgs<object> e) {
        Debug.Assert(false, "We should never actually be here!");
    }

Finally, here is the XAML from Window1 that covers the frame:

<!-- RHS Panel -->
    <Frame Name="Frame_RightPane" Grid.Column="0" Grid.ColumnSpan="1" Grid.Row="0" Grid.RowSpan="1" 
  Margin="201,65,0,0" HorizontalAlignment="Stretch" VerticalAlignment="Stretch" Height="Auto"/>

That's the best I can do here, but here is the link to the lab for anyone that really wants to understand it (http://windowsclient.net/downloads/folders/hands-on-labs/entry3719.aspx).

<--- END OF EDIT --->

Cheers,
Berryl

<-- exception -->

System.NullReferenceException was unhandled
Message="Object reference not set to an instance of an object." Source="mscorlib"
StackTrace:
   at System.Object.GetType()
   at MS.Internal.AppModel.ReturnEventSaver._Detach(PageFunctionBase pf)
   at System.Windows.Navigation.NavigationService.HookupNewTree(Object newTree, NavigateInfo navInfo, Uri newUri)
   at System.Windows.Navigation.NavigationService.OnBeforeSwitchContent(Object newBP, NavigateInfo navInfo, Uri newUri)
   at System.Windows.Navigation.NavigationService.MS.Internal.AppModel.IContentContainer.OnContentReady(ContentType contentType, Object bp, Uri bpu, Object navState)
   at System.Windows.Navigation.NavigationService.DoNavigate(Object bp, NavigationMode navFlags, Object navState)
   at System.Windows.Navigation.NavigateQueueItem.Dispatch(Object obj)
   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.DispatcherOperation.InvokeImpl()
   at System.Threading.ExecutionContext.runTryCode(Object userData)
   at System.Runtime.CompilerServices.RuntimeHelpers.ExecuteCodeWithGuaranteedCleanup(TryCode code, CleanupCode backoutCode, Object userData)
   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.InvokeImpl(DispatcherPriority priority, TimeSpan timeout, Delegate method, Object args, Boolean isSingleParameter)
   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.TranslateAndDispatchMessage(MSG& msg)
   at System.Windows.Threading.Dispatcher.PushFrameImpl(DispatcherFrame frame)
   at System.Windows.Application.RunInternal(Window window)
   at AddressBook.MyApp.Main() in C:\Users\Berryl\Documents\Visual Studio 2008\Projects\UI related\DEV007 Building WPF Applications\Source\CS\Ex1\Task1\AddressBook\obj\Debug\MyApp.g.cs:line 0
   at System.AppDomain._nExecuteAssembly(Assembly assembly, String[] args)
   at Microsoft.VisualStudio.HostingProcess.HostProc.RunUsersAssembly()
   at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state)
   at System.Threading.ThreadHelper.ThreadStart()

InnerException:

A: 

Did you rename any of the classes - like Window1.xaml? I have seen similar failures in WPF projects when I have renamed the window class and missed some references. They are a number of them in the project in generated code. If you search the entire project for the old name you should be able to find orphaned references that might be causing the null ref.

That sounds like the kind of thing I'm looking for, but doesn't seem to be the case here.
Berryl
WPF automatically generates a good deal of C# when compiling - the MyApp.g.cs code in the above call stack is all generated by WPF. The MS.Win32 class is native (C++) code that in my experience does not produce very good error messages. It might help if you provided some more information on what you are trying to do.