visual tutorial studio presentacion español ejemplos desventajas c# wpf expression-blend

c# - tutorial - ¿Hay alguna forma de comprobar si WPF se está ejecutando actualmente en modo de diseño o no?



xaml (8)

¿Alguien sabe de alguna variable de estado global que esté disponible para que pueda verificar si el código se está ejecutando actualmente en modo de diseño (por ejemplo, en Blend o Visual Studio) o no?

Se vería algo como esto:

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

La razón por la que necesito esto es cuando mi aplicación se muestre en modo de diseño en Expression Blend, pero quiero que ViewModel use una "Clase de cliente de diseño" que contenga datos simulados que el diseñador puede ver en modo de diseño.

Sin embargo, cuando la aplicación se está ejecutando realmente, por supuesto quiero que ViewModel use la clase real del Cliente que devuelve datos reales.

Actualmente resuelvo esto haciendo que el diseñador, antes de que trabaje en él, vaya al ViewModel y cambie "ApplicationDevelopmentMode.Executing" a "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); } } }


Creo que estás buscando GetIsInDesignMode , que toma un DependencyObject.

Es decir.

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

Editar: al usar Silverlight / WP7, debe usar IsInDesignTool ya que GetIsInDesignMode veces puede devolver false en Visual Studio:

DesignerProperties.IsInDesignTool

Editar: Y finalmente, en aras de la integridad, el equivalente en las aplicaciones de WinRT / Metro / Windows Store es DesignModeEnabled :

Windows.ApplicationModel.DesignMode.DesignModeEnabled


Cuando Visual Studio auto generó código para mí, lo usé

if (!System.ComponentModel.DesignerProperties.GetIsInDesignMode(this)) { ... }


Hay otras formas (quizás más nuevas) de especificar datos de tiempo de diseño en WPF, como se menciona en esta respuesta relacionada .

Esencialmente, puede especificar datos de tiempo de diseño usando una instancia en tiempo de diseño de su ViewModel :

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

o al especificar datos de muestra en un archivo XAML :

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

SamplePage.xaml establecer las propiedades del archivo SamplePage.xaml en:

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

Los UserControl en mi etiqueta UserControl , así:

<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="...">

En tiempo de ejecución, desaparecen todas las etiquetas de tiempo de diseño "d:", por lo que solo obtendrá su contexto de datos en tiempo de ejecución, independientemente de cómo elija configurarlo.

Editar También puede necesitar estas líneas (no estoy seguro, pero parecen relevantes):

xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" mc:Ignorable="d"


Puedes hacer algo como esto:

DesignerProperties.GetIsInDesignMode(new DependencyObject());


Solo he probado esto con Visual Studio 2013 y .NET 4.5, pero funciona.

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

Aunque es posible que algunas configuraciones en Visual Studio cambien este valor a falso, si eso ocurre, podemos simplemente verificar si este nombre de recurso existe. Fue null cuando ejecuté mi código fuera del diseñador.

El lado positivo de este enfoque es que no requiere un conocimiento explícito de la clase de App específica y que se puede usar globalmente en todo su código. Específicamente para poblar modelos de vista con datos ficticios.


Tengo una idea para ti si tu clase no necesita un constructor vacío.

La idea es crear un constructor vacío, luego marcarlo con ObsoleteAttribute. El diseñador ignora el atributo obsoleto, pero el compilador generará un error si intenta usarlo, por lo que no existe el riesgo de utilizarlo accidentalmente.

( perdón por mi visual básico )

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

Y el 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>

Esto no funcionará si realmente necesita el constructor vacío para otra cosa.


Y si utiliza extensamente Caliburn.Micro para su aplicación WPF / Silverlight / WP8 / WinRT grande, puede usar propiedades estáticas Execute.InDesignMode prácticas y universales de Execute.InDesignMode en sus modelos de vista también (y funciona tanto en Blend como en 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" //}; } }


public static bool InDesignMode() { return !(Application.Current is App); }

Funciona desde cualquier lugar. Lo uso para detener la reproducción de videos de datos en el diseñador.