WPF Debugging -- "Unable to cast object of type 'System.Windows.Controls.Grid' to type 'System.Windows.Window'

I hunted down a kind of a tricky error message today, and thought I'd write a quick post about it.

The Scenario:

I was doing some refactoring of a WPF app, encapsulating a section of one large-ish UserControl into a second UserControl. 

  • Prior to the refactoring, the single combined UserControl was running directly as the StartupURI of a test harness app.xaml, which resulted in it being hosted in a NavigationWindow when run
  • The new extracted User Control contained most of the business functionality of the containing control
  • The original UserControl was converted into a Window, containing a Grid, which then contained the extracted UserControl

The Error:

In the designer and at runtime, the following dialog popped up one time:

image

As soon as the dialog was cleared, both the designer surface and the app worked as expected.

The Solution:

It turns out that I had two lines in the constructor of my original user control (for positioning of the hosting window), which I had moved to the constructor in the extracted UserControl, which referenced the parent cast as a Window:

((Window)Parent.Left = 0;
((Window)Parent).Top = 0;

Obvious -- the Designer and WPF at runtime both evaluated this code, and since the parent was no longer a Window, the cast didn't work.

I moved these lines into the constructor and this resolved the issue.

Summary:

I'm not surprised that the error was thrown, but I was interested in two aspects:

  1. The Designer (Cider) evaluated the constructor code in the UserControl to the point that it threw casting errors on the Parent property.  I guess this is necessary to make sure everything renders correctly in the Designer surface, but I shudder to think of the amount of logic that Visual Studio must run to decide what code to run and what to ignore when loading up the Designer surface.
  2. At runtime, WPF handled this error and generated its own error dialog, rather than throwing an unhandled exception.  This would've been a lot easier to debug if it had thrown like a normal unhandled exception in Visual Studio.

All in all, it was an interesting exercise.

No Comments