3

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?

Sinatr
  • 20,892
  • 15
  • 90
  • 319
  • What is "My"?, if "My" is a static field then your binding is wrong, it should be something like this – adminSoftDK Jan 08 '16 at 09:16
  • 1
    @adminSoftDK, it's not a binding, but a [markup extension](http://10rem.net/blog/2011/03/09/creating-a-custom-markup-extension-in-wpf-and-soon-silverlight): `MyExtension` (word "Extension" is omitted when using extension in the xaml, similar to attributes). – Sinatr Jan 08 '16 at 09:30
  • Why don't you set `MyExtension.Test = true` in the `App` constructor instead? – Mike Eason Jan 08 '16 at 09:42
  • 1
    @MikeEason, `App` is not used when window is rendered in the designer. It would work during run-time, but I am interested in both: design-time and run-time, therefore I tried to use static constructor... which doesn't work in design time upon VS startup. – Sinatr Jan 08 '16 at 09:44

1 Answers1

3

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.

Il Vic
  • 5,576
  • 4
  • 26
  • 37
  • Even if it works idea with subclassing every control doesn't sounds very appealing. Or do you mean to create just one *fake* `UserControl` (or custom control?) to run custom code for **window** (containing that control)? – Sinatr Jan 11 '16 at 08:14
  • @Sinatr, since we are talking about a static constructor, I mean _just one_ "fake" extended control. Its purpose is just to initialize your extensions' values (like `MyExtension`). So each `Window` needs to contain just one instance of our "fake" control. – Il Vic Jan 11 '16 at 08:42
  • You are right @Sinatr, I agree: it is a sad workaround. But since the designer works in that way, I guess there are not so many other solutions. – Il Vic Jan 11 '16 at 09:34
  • I had a brilliant idea to move initialization into attached property (e.g. setting attached property for window).. to find out what attached property is set **after** markup extensions... – Sinatr Jan 11 '16 at 11:01
  • I'm sorry, I misunderstood you last comment. Now I see your solution does not work – Il Vic Jan 11 '16 at 14:08