WPF designer doesn't run window static constru

2019-05-13 16:28发布

问题:

When I load solution and there is an opened designer tab for some window, then this window static constructor is not executed.

Perhaps my conclusion is wrong (because I am absolutely clueless how designer load things), but here is a test case:

  1. Create new WPF project.

  2. Create simple extension

public class MyExtension : MarkupExtension
{
    public static bool Test;
    public override object ProvideValue(IServiceProvider serviceProvider) => Test.ToString();
}
  1. Add to main window

<TextBlock Text="{local:My}" />

and

static MainWindow()
{
    MyExtension.Test = true;
}
  1. Now compile it (F6), TextBlock should show True in designer.
  2. Do not close designer window. Close VS.
  3. Start solution (double-click sln file).
  4. As soon as designer loads window you will see TextBlock display False.

WTF? Can someone confirm that (or is it my VS 2015 bug)?

I would really like to know how designer works: how window is loaded, which events/methods are used, etc. It seems window constructor (non-static one) is not executed (anything put there is not happening in design time), how is the window then created and displayed?

回答1:

I know how it works for Visual Studio 2010 and reading your question I suppose that the same principles may be also applied to Visual Studio 2015.

When a control is rendered inside the XAML designer (regarding VS2010 it is called Cider ) as the main control (i.e. a Window) its constructor is not run. On the other side, if a control is a child of another control which is rendered inside the XAML designer, the first control's constructor is executed (i.e. a UserControl inside a Window). You can read more about it here.

So you need to move the My.Test initialization into a customized control, for example:

public class MyTextBlock : TextBlock
{
    static MyTextBlock()
    {
        MyExtension.Test = true;
    }
}

Then use it inside your Window:

<local:MyTextBlock Text="{local:My}" />

After you compile your project, you will see the "True" text in the designer. I repeat: it works for Visual Studio 2010, so I hope it can represent an hint to solve your issue.