Quelqu'un sait-il qu'il existe une variable d'état globale disponible pour que je puisse vérifier si le code est en cours d'exécution en mode conception (par exemple, dans Blend ou Visual Studio) ou non?
Cela ressemblerait à quelque chose comme ça:
//pseudo code:
if (Application.Current.ExecutingStatus == ExecutingStatus.DesignMode)
{
...
}
La raison pour laquelle j'ai besoin de cela est la suivante: lorsque mon application est affichée en mode conception dans Expression Blend, je souhaite que ViewModel utilise à la place une "classe de client de conception" qui contient des données fictives que le concepteur peut afficher en mode création.
Cependant, lorsque l'application est en cours d'exécution, je souhaite bien sûr que le ViewModel utilise la classe Customer réelle qui renvoie des données réelles.
Actuellement, je résous ce problème en demandant au concepteur, avant qu'il ne travaille dessus, d'accéder au ViewModel et de remplacer "ApplicationDevelopmentMode.Executing" par "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);
}
}
}
Je crois que vous recherchez GetIsInDesignMode , qui prend un DependencyObject.
C'est à dire.
// 'this' is your UI element
DesignerProperties.GetIsInDesignMode(this);
Edit: Lorsque vous utilisez Silverlight/WP7, vous devez utiliser IsInDesignTool
puisque GetIsInDesignMode
peut renvoient parfois false dans Visual Studio:
DesignerProperties.IsInDesignTool
Edit: Et enfin, dans un souci de complétude, l'équivalent dans les applications WinRT/Metro/Windows Store est DesignModeEnabled
:
Windows.ApplicationModel.DesignMode.DesignModeEnabled
Vous pouvez faire quelque chose comme ça:
DesignerProperties.GetIsInDesignMode(new DependencyObject());
public static bool InDesignMode()
{
return !(Application.Current is App);
}
Fonctionne de n'importe où. Je l'utilise pour empêcher la lecture de vidéos de base de données dans le concepteur.
Lorsque Visual Studio a généré du code pour moi, il a utilisé
if (!System.ComponentModel.DesignerProperties.GetIsInDesignMode(this))
{
...
}
Il existe d'autres moyens (peut-être plus récents) de spécifier des données de conception dans WPF, par exemple mentionné dans cette réponse .
Pour l'essentiel, vous pouvez spécifier des données de conception à l'aide d'un instance de conception de votre ViewModel :
d:DataContext="{d:DesignInstance Type=v:MySampleData, IsDesignTimeCreatable=True}"
ou par en spécifiant des exemples de données dans un fichier XAML :
d:DataContext="{d:DesignData Source=../DesignData/SamplePage.xaml}">
Vous devez définir le SamplePage.xaml
propriétés du fichier à:
BuildAction: DesignData
Copy to Output Directory: Do not copy
Custom Tool: [DELETE ANYTHING HERE SO THE FIELD IS EMPTY]
Je les place dans ma balise UserControl
, comme ceci:
<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="...">
Au moment de l'exécution, toutes les balises de conception "d:" disparaissent, de sorte que vous n'obtiendrez que votre contexte de données d'exécution, quelle que soit votre définition.
Modifier Vous pourriez aussi avoir besoin de ces lignes (je n'en suis pas certaine, mais elles semblent pertinentes):
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d"
Et si vous utilisez intensément Caliburn.Micro pour votre grand WPF/Silverlight/WP8/WinRT , vous pouvez utiliser un outil pratique et universel de caliburn Execute.InDesignMode
propriété statique dans vos modèles de vue également (et cela fonctionne aussi bien dans Blend que dans 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"
//};
}
}
La réponse acceptée n'a pas fonctionné pour moi (VS2019).
Après avoir inspecté ce qui se passait, je trouvai ceci:
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");
}
}
Je n'ai testé cela qu'avec Visual Studio 2013 et .NET 4.5, mais cela fait l'affaire.
public static bool IsDesignerContext()
{
var maybeExpressionUseLayoutRounding =
Application.Current.Resources["ExpressionUseLayoutRounding"] as bool?;
return maybeExpressionUseLayoutRounding ?? false;
}
Il est toutefois possible que certains paramètres de Visual Studio fassent passer cette valeur à false. Si cela se produit, nous pouvons simplement vérifier si ce nom de ressource existe. C'était null
lorsque j'ai exécuté mon code en dehors du concepteur.
L'avantage de cette approche est qu'elle ne nécessite pas de connaissance explicite de la classe spécifique App
et qu'elle peut être utilisée globalement dans tout votre code. Spécifiquement pour remplir les modèles de vue avec des données factices.
J'ai une idée pour vous si votre classe n'a pas besoin d'un constructeur vide.
L'idée est de créer un constructeur vide, puis de le marquer avec ObsoleteAttribute. Le concepteur ignore l'attribut obsolète, mais le compilateur générera une erreur si vous essayez de l'utiliser, il n'y a donc aucun risque de l'utiliser accidentellement vous-même.
( pardonnez mon visuel de base )
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
Et le 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>
Cela ne fonctionnera pas si vraiment avez besoin du constructeur vide pour autre chose.