162

Does anyone know of some global state variable that is available so that I can check if the code is currently executing in design mode (e.g. in Blend or Visual Studio) or not?

It would look something like this:

//pseudo code:
if (Application.Current.ExecutingStatus == ExecutingStatus.DesignMode) 
{
    ...
}

The reason I need this is: when my application is being shown in design mode in Expression Blend, I want the ViewModel to instead use a "Design Customer class" which has mock data in it that the designer can view in design mode.

However, when the application is actually executing, I of course want the ViewModel to use the real Customer class which returns real data.

Currently I solve this by having the designer, before he works on it, go into the ViewModel and change "ApplicationDevelopmentMode.Executing" to "ApplicationDevelopmentMode.Designing":

public CustomersViewModel()
{
    _currentApplicationDevelopmentMode = ApplicationDevelopmentMode.Designing;
}

public ObservableCollection<Customer> GetAll
{
    get
    {
        try
        {
            if (_currentApplicationDevelopmentMode == ApplicationDevelopmentMode.Developing)
            {
                return Customer.GetAll;
            }
            else
            {
                return CustomerDesign.GetAll;
            }
        }
        catch (Exception ex)
        {
            throw new Exception(ex.Message);
        }
    }
}
Edward Tanguay
  • 189,012
  • 314
  • 712
  • 1,047

9 Answers9

252

I believe you are looking for GetIsInDesignMode, which takes a DependencyObject.

Ie.

// 'this' is your UI element
DesignerProperties.GetIsInDesignMode(this);

Edit: When using Silverlight / WP7, you should use IsInDesignTool since GetIsInDesignMode can sometimes return false while in Visual Studio:

DesignerProperties.IsInDesignTool

Edit: And finally, in the interest of completeness, the equivalent in WinRT / Metro / Windows Store applications is DesignModeEnabled:

Windows.ApplicationModel.DesignMode.DesignModeEnabled
Richard Szalay
  • 83,269
  • 19
  • 178
  • 237
  • 4
    As a side note, IsInDesignMode is actually an attached property, so you can use it in a binding from xaml as well. Might not be the most common use though :) – aL3891 May 23 '11 at 13:10
  • 4
    Thanks for keeping the answer up to date with latest XAML "applications" like WinRT and WP. – Sevenate Nov 12 '13 at 11:01
  • In VS2019 switch `Enable project code` must be enabled (or Menu->Design-> Run Project Code). – marbel82 Feb 18 '20 at 08:04
137

You can do something like this:

DesignerProperties.GetIsInDesignMode(new DependencyObject());
Sacha Bruttin
  • 4,083
  • 2
  • 21
  • 17
  • 39
    This method also works for making ViewModels designer-friendly (since they are not DependencyObjects themselves). – Pat Jun 20 '11 at 23:04
  • 1
    DependencyObject has a protected constructor - define `internal class MyDependencyObject : DependencyObject {}` and use `new MyDependencyObject` instead of `DependencyObject` – Rico Suter Sep 14 '11 at 21:15
  • 3
    @RicoSuter: [`DependencyObject`'s constructor is `public`.](https://msdn.microsoft.com/en-us/library/system.windows.dependencyobject.dependencyobject(v=vs.85).aspx) – Peter Duniho Oct 28 '15 at 23:25
  • 1
    if doing this in a viewmodel you probably want to abstract it away into a static class and store the result as a static boolean – Simon_Weaver Jan 12 '17 at 20:39
33
public static bool InDesignMode()
{
    return !(Application.Current is App);
}

Works from anywhere. I use it to stop databound videos from playing in the designer.

weston
  • 54,145
  • 21
  • 145
  • 203
Patrick
  • 1,766
  • 1
  • 15
  • 27
  • A variation on the above `Application.Current.MainWindow == null` though I like the type test better, more direct. It also appears as if the designer hosted in Visual Studio adds resources, so here's another way to do it (if you don't have access to the specific `App` type in the library hosting your code) `((bool)Application.Current.Resources["ExpressionUseLayoutRounding"])`. Need checks if the resource is not there though but it does work in designer context. – John Leidegren Aug 26 '15 at 11:55
  • 3
    This answer doesn't work anywhere. For instance, in a library you don't have the App class. ;) – GregorMohorko Oct 29 '20 at 23:13
  • @GregorMohorko It's the right answer if you need to check this in the static constructor of `App`. – Martin Braun Nov 28 '21 at 21:48
  • @MartinBraun Yes, there it will work. I was replying to his `Works from anywhere.` claim. – GregorMohorko Nov 29 '21 at 09:53
  • @GregorMohorko Sorry yes, mis-read your words as "everywhere". You are right, you need to have access to `App` and I would even consider it bad to access `App` from anything but `App` itself to ensure modularity. – Martin Braun Nov 30 '21 at 14:12
  • It seems `Application.Current is App` returns false in Release mode and I don't know why. – Martin Braun Jan 13 '22 at 14:19
  • Thats pretty useful if you have no DependencyObject in your context. – Kamil Aug 04 '22 at 22:56
11

There are other (maybe newer) ways of specifying design-time data in WPF, as mentioned in this related answer.

Essentially, you can specify design-time data using a design-time instance of your ViewModel:

d:DataContext="{d:DesignInstance Type=v:MySampleData, IsDesignTimeCreatable=True}"

or by specifying sample data in a XAML file:

d:DataContext="{d:DesignData Source=../DesignData/SamplePage.xaml}">

You have to set the SamplePage.xaml file properties to:

BuildAction:               DesignData
Copy to Output Directory:  Do not copy
Custom Tool:               [DELETE ANYTHING HERE SO THE FIELD IS EMPTY]

I place these in my UserControl tag, like this:

<UserControl
    ...
    xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 

    xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
    ...
    d:DesignWidth="640" d:DesignHeight="480"
    d:DataContext="...">

At run-time, all of the "d:" design-time tags disappear, so you'll only get your run-time data context, however you choose to set it.

Edit You may also need these lines (I'm not certain, but they seem relevant):

xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
mc:Ignorable="d" 
Community
  • 1
  • 1
cod3monk3y
  • 9,508
  • 6
  • 39
  • 54
9

When Visual Studio auto generated some code for me it used

if (!System.ComponentModel.DesignerProperties.GetIsInDesignMode(this)) 
{
    ...
}
Darren
  • 427
  • 1
  • 5
  • 11
7

And if you extensively use Caliburn.Micro for your large WPF / Silverlight / WP8 / WinRT application you could use handy and universal caliburn's Execute.InDesignMode static property in your view-models as well (and it works in Blend as good as in Visual Studio):

using Caliburn.Micro;

// ...

/// <summary>
/// Default view-model's ctor without parameters.
/// </summary>
public SomeViewModel()
{
    if(Execute.InDesignMode)
    {
        //Add fake data for design-time only here:

        //SomeStringItems = new List<string>
        //{
        //  "Item 1",
        //  "Item 2",
        //  "Item 3"
        //};
    }
}
Martin Braun
  • 10,906
  • 9
  • 64
  • 105
Sevenate
  • 6,221
  • 3
  • 49
  • 75
4

Accepted answer didn't work for me (VS2019).

After inspecting what was going on, I came up with this:

    public static bool IsRunningInVisualStudioDesigner
    {
        get
        {
            // Are we looking at this dialog in the Visual Studio Designer or Blend?
            string appname = System.Reflection.Assembly.GetEntryAssembly().FullName;
            return appname.Contains("XDesProc");
        }
    }
Ger Hobbelt
  • 1,126
  • 1
  • 11
  • 16
  • This worked for me where I needed to know if I was running in design time from within a viewModel and couldn't use Windows libraries. I know it's a very small amount of reflection but I didn't like the thought of it running in production so I wrapped this code in an `#if DEBUG` else return false. Is there any reason to not do that? – Toby Smith Aug 27 '19 at 18:33
  • I tried this technique in VS2022 and .NET 6, but the appname I get is `WpfSurface` instead. – Arturo Torres Sánchez Feb 24 '22 at 01:49
2

I've only tested this with Visual Studio 2013 and .NET 4.5 but it does the trick.

public static bool IsDesignerContext()
{
  var maybeExpressionUseLayoutRounding =
    Application.Current.Resources["ExpressionUseLayoutRounding"] as bool?;
  return maybeExpressionUseLayoutRounding ?? false;
}

It's possible though that some setting in Visual Studio will change this value to false, if that ever happens we can result to just checking whether this resource name exist. It was null when I ran my code outside the designer.

The upside of this approach is that it does not require explicit knowledge of the specific App class and that it can be used globally throughout your code. Specifically to populate view models with dummy data.

John Leidegren
  • 59,920
  • 20
  • 131
  • 152
2

I have an idea for you if your class doesn't need an empty constructor.

The idea is to create an empty constructor, then mark it with ObsoleteAttribute. The designer ignores the obsolete attribute, but the compiler will raise an error if you try to use it, so there's no risk of accidentaly using it yourself.

(pardon my visual basic)

Public Class SomeClass

    <Obsolete("Constructor intended for design mode only", True)>
    Public Sub New()
        DesignMode = True
        If DesignMode Then
            Name = "Paula is Brillant"
        End If
    End Sub

    Public Property DesignMode As Boolean
    Public Property Name As String = "FileNotFound"
End Class

And the xaml:

<UserControl x:Class="TestDesignMode"
             xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
             xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
             xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
             xmlns:vm="clr-namespace:AssemblyWithViewModels;assembly=AssemblyWithViewModels"
             mc:Ignorable="d" 
             >
  <UserControl.Resources>
    <vm:SomeClass x:Key="myDataContext" />
  </UserControl.Resources>
  <StackPanel>
    <TextBlock d:DataContext="{StaticResource myDataContext}" Text="{Binding DesignMode}" Margin="20"/>
    <TextBlock d:DataContext="{StaticResource myDataContext}" Text="{Binding Name}" Margin="20"/>
  </StackPanel>
</UserControl>

result of the above code

This won't work if you really need the empty constructor for something else.

DonkeyMaster
  • 1,302
  • 4
  • 17
  • 36