WPF Design time preprocessing issue

Right, this was irritating. I was working on a project where I had a WPF Window base class with a somewhat complex constructor content. This caused the designer to crash whenever I was trying to open it on one of my deriving windowses. The code in the constructor was not in error in anyway, it still just crashed.
Here’s a short example of how to get a similar problem and how to solve it:

public class BaseWindow : Window
{
    protected string m_TextFileContent;
 
    public BaseWindow()
    {
        using (Stream stream = Assembly.GetExecutingAssembly()
                                   .GetManifestResourceStream("test.txt"))
        {
            using (StreamReader reader = new StreamReader(stream))
            {
                m_TextFileContent = reader.ReadToEnd();
            }
        }
    }
}
 
public partial class Window1 : BaseWindow
{
    public Window1()
    {
        InitializeComponent();
        this.Title = m_TextFileContent;
    }
}
<base:BaseWindow x:Class="WpfTest.Window1"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:base="clr-namespace:WpfTest"
    Title="Window1" Height="300" Width="300" xmlns:my="http://schemas.microsoft.com/wpf/2008/toolkit">
    <Grid></Grid>
</base:BaseWindow>

With that code your application will not build and it will look something like this in your designer:

The designer is not working
*crash*

The reason for this is that the designer needs to be able to create an instance of your base class in design time and it can’t open and read files in that state. So, we need to check if we are in design mode or running in the base construct:

public class BaseWindow : Window
{
    protected string m_TextFileContent;
 
    public BaseWindow()
    {
        if (!DesignerProperties.GetIsInDesignMode(this))
        {
            using (Stream stream = Assembly.GetExecutingAssembly()
                                       .GetManifestResourceStream("test.txt"))
            {
                using (StreamReader reader = new StreamReader(stream))
                {
                    m_TextFileContent = reader.ReadToEnd();
                }
            }
        }
    }
}

Now, to do such a thing the constructor is stupid and shouldn’t be done, but just as an example 🙂

Leave a Reply