Detecting design time mode in WPF and Silverlight

We already talked often about providing design time data to your designers in Windows Presentation Foundation and in Silverlight, thus enabling them to work visually in design editors such as Expression Blend or the Visual Studio designer (codenamed Cider).

The goal here is very simple: Designers should see something on their design surface. This sounds simple, but it can get quite tricky. Since Blend and Cider run (parts of) your application’s code to render the WPF or Silverlight elements, you need to make sure that the whole code can be executed safely. For some simple operations, it is not a problem (for example, getting today’s date and time is something that Blend and Cider can do easily) but others are more difficult. Here are two examples off the top of my head:

  • Connecting to a database to get data: Since the code that runs in Blend or Cider is executed in a different context than in the real application, this kind of code will fail in Blend/Cider and should be replaced by something else.
  • Getting data from the internet: Here too, most attempts to connect to the internet from Blend/Cider will fail. In the best case you will still see your data controls, but they will be empty. In the worst case you might even get an exception in Blend, which will hide everything on the design surface.

Detecting this kind of issues requires a bit of experience, and to be very systematic. Thankfully you can easily attach a debugger to Expression Blend and execute the code from your application that Blend is running (how else did you think I found out how Blend works and developed my MVVM Light Toolkit? ;)) Attaching the debugger to Blend will be the topic for a next article.

Isolating/Replacing the code

Once you detected the offending lines in your code (and if you do WPF and Silverlight right, this will probably be within your View Model classes), you should provide something else to Blend/Cider to execute. But how can you make sure that you are executing this code in a design time editor and not at runtime?

In fact this is a bit tricky. The problem is that there are a few, very different scenarios that need to be supported:

Running environment IsInDesignMode
WPF element within Expression Blend True
Silverlight element within Expression Blend True
WPF element within Cider True
Silverlight element within Cider N/A (no Silverlight designer in Visual Studio for now)
WPF application (runtime) False
Silverlight application (runtime) False
WPF user control embedded in a Windows Forms application (runtime) False
WPF user control embedded in a Windows Forms application within Blend N/A (Blend can open, but not render Windows Forms applications)
WPF user control embedded in a Windows Forms application within Cider True

Yeah, I am pretty sure that many of you guys forgot that WPF user controls can be embedded in a Windows Forms application. I am guilty of not having tested this particular case in my MVVM Light Toolkit, and the IsInDesignMode property will return true even when the WinForms application is running, forcing the WPF user control to use design time data. Not good (this particular bug is corrected already and will be published in the next few days with V1.1.1 of the MVVM Light Toolkit).

Providing the IsInDesignMode property

I spent a bit of time talking to friends and checking the web, trying to find a unified code that would work in all situations. As much as I can, I try to get the exact same code to run in WPF and in Silverlight (most of the MVVM toolkit’s code is actually shared between WPF and SL), but in that particular case, nothing seemed to work reliably in both environments. So my solution is:

private static bool? _isInDesignMode;

/// <summary>
/// Gets a value indicating whether the control is in design mode (running in Blend
/// or Visual Studio).
/// </summary>
public static bool IsInDesignModeStatic
{
    get
    {
        if (!_isInDesignMode.HasValue)
        {
#if SILVERLIGHT
            _isInDesignMode = DesignerProperties.IsInDesignTool;
#else
            var prop = DesignerProperties.IsInDesignModeProperty;
            _isInDesignMode
                = (bool)DependencyPropertyDescriptor
                .FromProperty(prop, typeof(FrameworkElement))
                .Metadata.DefaultValue;
#endif
        }

        return _isInDesignMode.Value;
    }
}

Known issues

There is one known issue with this code though: When you open the WinForms designer with the embedded WPF user control in Cider, the code returns false, and thus the runtime mode data is used. This might be a problem because runtime data can crash the designer and nothing will be rendered. After turning the problem in my head a few nights, I decided that this would just be a documented bug. If you are in the situation where you must absolutely use the Windows Forms designer in Cider, and you have an embedded WPF user control in your window, and the designer crashes, I recommend commenting out the code that causes the crash, designing your WinForms window, and then restoring the code. This is annoying, granted, but I don’t have a better solution right now. If anyone knows a way around this problem, please feel free to leave a comment!!

Usage

This property is used over and over again as soon as you do development in Blend. It makes sense to expose it in a way that makes it easy to use.

In my MVVM Light Toolkit, the property is a static property of the ViewModelBase class. This makes it very easy to use in the source code. However, binding to a static property is a bit cumbersome in WPF and impossible in Silverlight. So I also provide a non static property, that is just a wrapper around the static one. The full code is found below. Using the property becomes:

In XAML:

<Window x:Class="MvvmLight6.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Height="400"
        Width="300"
        DataContext="{Binding Main, Source={StaticResource Locator}}">
    
    <Window.Resources>
        <BooleanToVisibilityConverter x:Key="BooleanToVisibilityConverter" />
    </Window.Resources>

    <Grid>
        <TextBlock Text="Design mode only!!"
            Visibility="{Binding IsInDesignMode, 
                Converter={StaticResource BooleanToVisibilityConverter}}" />
    </Grid>
</Window>

In C# (within the View Model)

public MainViewModel()
{
    if (IsInDesignMode)
    {
        // Code runs in Blend -->
        // create design time data.
    }
    else
    {
        // Code runs in runtime -->
        // Connect to DB, services, etc...
    }
}

In C# (outside of the View Model)

public MainWindow()
{
    this.InitializeComponent();

    if (!ViewModelBase.IsInDesignModeStatic)
    {
        this.Closing += (s, e) => ViewModelLocator.Dispose();
    }
}

The full code

The whole property, including static and non-static accessor is:

private static bool? _isInDesignMode;

/// <summary>
/// Gets a value indicating whether the control is in design mode (running in Blend
/// or Visual Studio).
/// </summary>
public static bool IsInDesignModeStatic
{
    get
    {
        if (!_isInDesignMode.HasValue)
        {
#if SILVERLIGHT
            _isInDesignMode = DesignerProperties.IsInDesignTool;
#else
            var prop = DesignerProperties.IsInDesignModeProperty;
            _isInDesignMode
                = (bool)DependencyPropertyDescriptor
                .FromProperty(prop, typeof(FrameworkElement))
                .Metadata.DefaultValue;
#endif
        }

        return _isInDesignMode.Value;
    }
}

/// <summary>
/// Gets a value indicating whether the control is in design mode (running under Blend
/// or Visual Studio).
/// </summary>
[SuppressMessage(
    "Microsoft.Performance",
    "CA1822:MarkMembersAsStatic",
    Justification = "Non static member needed for data binding")]
public bool IsInDesignMode
{
    get
    {
        return IsInDesignModeStatic;
    }
}
  • Share This Post:
  • Share on Twitter
  • Share on Facebook
  • Share on Technorati
Print | posted on Saturday, September 05, 2009 12:07 AM

Feedback

# re: Detecting design time mode in WPF and Silverlight

left by Daniel Vaughan at 9/5/2009 1:42 AM Gravatar
Very useful. Thanks Laurent.

# Possibly solution?

left by Grumpydev at 9/5/2009 5:49 AM Gravatar
This is a possible solution, if a little messy. I've tested it with a WPF app and a WPF control in a WinForms app. I've also added an additional conditional that always returns "false" if we aren't in debug mode so our release software doesn't have to bother checking:

private static bool? _isInDesignMode;

/// <summary>
/// Gets a value indicating whether the control is in design mode (running in Blend
/// or Visual Studio).
/// </summary>
public static bool IsInDesignModeStatic
{
get
{
if (!_isInDesignMode.HasValue)
{
#if DEBUG
#if SILVERLIGHT
_isInDesignMode = DesignerProperties.IsInDesignTool;
#else
var prop = DesignerProperties.IsInDesignModeProperty;
_isInDesignMode
= (bool)DependencyPropertyDescriptor
.FromProperty(prop, typeof(FrameworkElement))
.Metadata.DefaultValue;

if (!_isInDesignMode.Value)
if (System.Diagnostics.Process.GetCurrentProcess().ProcessName.StartsWith(@"devenv"))
_isInDesignMode = true;
#endif

#else
_isInDesignMode = false;
#endif
}
return _isInDesignMode.Value;
}
}

# re: Detecting design time mode in WPF and Silverlight

left by Laurent at 9/5/2009 6:47 AM Gravatar
@Daniel, thanks!

@Steve: You know, it's funny, but the other day I was chatting with Josh Smith and he told me "why don't you just check the process name" LOL

You know what, what the heck, I will just use your solution. If you and Josh Smith both think it is viable, it is more than good enough for me ha ha ha.

Nice touch about the #if DEBUG too. It makes sense, since Blend always runs the DEBUG config anyway.

Cheers,
Laurent

# re: Detecting design time mode in WPF and Silverlight

left by Grumpydev at 9/5/2009 7:01 AM Gravatar
My only concern with the debug conditional would be for people shipping binary controls. If they only ship release builds then design mode won't work. No idea if anyone would actually do that though :-)

# re: Detecting design time mode in WPF and Silverlight

left by Laurent at 10/4/2009 12:16 AM Gravatar
Update: In V2 of the MVVM Light Toolkit, I removed the #if DEBUG which was indeed causing issues in release mode. It was a bad good idea :) The result is now consistent again in Release and in Debug mode.

# re: Detecting design time mode in WPF and Silverlight

left by Tee at 9/28/2010 12:53 AM Gravatar
Hi Laurent,

I am running Expression Blend 4 (RTM) for Windows phone 7 and VS 2010 Express (RTM), and neither IsInDesignModeStatic nor IsInDesignTool return true when running in expression blend 4.

Is it because I am running the express versions?

# re: Detecting design time mode in WPF and Silverlight

left by Laurent at 9/28/2010 4:33 AM Gravatar
Hi,

No it should work just fine. That's weird. Can you try to check if DesignerProperties.IsInDesignTool returns true?

Thanks,
Laurent

# re: Detecting design time mode in WPF and Silverlight

left by Christopher at 11/26/2010 1:25 PM Gravatar
Thank you! This made my day!

# re: Detecting design time mode in WPF and Silverlight

left by Michael Tilelli at 1/10/2011 7:04 PM Gravatar
I found this code to be useful in code behind:

public override void EndInit()
{
if (!DesignerProperties.GetIsInDesignMode(this))
{
// insert code here
}
base.EndInit();
}

Then you don't need to write an extra method

# re: Detecting design time mode in WPF and Silverlight

left by Laurent at 1/11/2011 8:50 AM Gravatar
Hi,

It does not work in WPF. This is why I abstracted this in the MVVM Light toolkit.

Cheers,
Laurent

# re: Detecting design time mode in WPF and Silverlight

left by Jordan at 3/30/2011 8:46 PM Gravatar
Great Stuff Laurent, Thank You!

# re: Detecting design time mode in WPF and Silverlight

left by Christian Scott at 5/20/2011 7:55 AM Gravatar
It seems Blend 4 actually runs the code-behind without problems so you don't need to differentiate between design/runtime. Can anyone confirm?

Regards,
Christian

# re: Detecting design time mode in WPF and Silverlight

left by Laurent Bugnion at 5/20/2011 8:36 AM Gravatar
Hi,

Three things:

• Strictly speaking Blend does not run code behind, but only code that is hooked in the resources in XAML. This is how MVVM Light applications are "wired", for this exact reason.
• Some code runs just fine, but other code fails in Blend. Typically calls to web services or attempts to get data from database will not run in Blend and you will even in some cases get exceptions which prevent to do any visual work.
• Even when the code runs, it can be impossible to get actual data in Blend, for instance if there is a login needed.

In all those cases, design time detection is your friend.

Cheers
Laurent

# re: Detecting design time mode in WPF and Silverlight

left by Christian Scott at 5/20/2011 12:10 PM Gravatar
Thanks. I tried coercing Blend into throwing exceptions by doing some async file reading and stuff. Didn't try the cases you mention.

I would like to request some videos where you do everything MVVM Light Toolkit does, but without MVVM Light Toolkit, and then code the Toolkit from bottom up to show the true benefits. If you're a newbie to WPF/SL/MVVM, the toolkit smooths over stuff you might never fully understand which could be a disadvantage.

Have a great day!

Christian

# re: Detecting design time mode in WPF and Silverlight

left by Luke Puplett at 10/13/2011 1:36 PM Gravatar
Sorry if I'm talking about old stuff but checking the process name might cause a problem for partial trust apps.

MSDN:

[The Process] class contains a link demand and an inheritance demand at the class level that applies to all members. A SecurityException is thrown when either the immediate caller or the derived class does not have full-trust permission. For details about security demands, see Link Demands and Inheritance Demands
Post A Comment
Title:
Name:
Email:
Website:
Comment:
Verification: