¿Qué enfoques están disponibles para los datos ficticios en tiempo de diseño en WPF?

97

Estoy trabajando sin una combinación de expresiones y solo estoy usando el editor XAML en vs2010. Dejando a un lado la sabiduría de esto, cada vez veo más la necesidad de vincular datos en tiempo de diseño. Para casos simples, la FallbackValuepropiedad funciona muy bien (Textboxes y TextBlocks, etc.). Pero especialmente cuando se trata de ItemsControly similares, uno realmente necesita que los datos de muestra sean visibles en el diseñador para que pueda ajustar y modificar los controles y las plantillas de datos sin tener que ejecutar el ejecutable.

Sé que ObjectDataProviderpermite la vinculación a un tipo y, por lo tanto, puede proporcionar datos en tiempo de diseño para visualizar, pero luego hay algunos malabarismos para permitir que los datos reales en tiempo de ejecución se vinculen sin desperdiciar recursos cargando tanto el tiempo de diseño como el tiempo de diseño. datos ficticios y los enlaces de tiempo de ejecución.

Lo que realmente quiero es la capacidad de tener, por ejemplo, "John", "Paul", "George" y "Ringo" en el diseñador XAML como elementos con estilo en mi ItemsControl, pero que se muestren datos reales cuando la aplicación carreras.

También sé que Blend permite algunos atributos sofisticados que definen datos de enlace de tiempo de diseño que WPF ignora de manera efectiva en condiciones de tiempo de ejecución.

Entonces mis preguntas son:

1. ¿Cómo puedo aprovechar los enlaces en tiempo de diseño de las colecciones y los datos no triviales en el diseñador XAML de Visual Studio y luego cambiar a los enlaces en tiempo de ejecución sin problemas?

2. ¿Cómo han resuelto otros este problema de datos de tiempo de diseño frente a tiempo de ejecución? En mi caso, no puedo usar fácilmente los mismos datos para ambos (como podría hacerlo con, digamos, una consulta de base de datos).

3. ¿Son sus alternativas a la combinación de expresiones que podría usar para el diseño XAML integrado en datos? (Sé que hay algunas alternativas, pero quiero específicamente algo que pueda usar y ver datos de muestra vinculados, etc.)

el2iot2
fuente

Respuestas:

120

Con VS2010 puede usar atributos de tiempo de diseño (funciona tanto para SL como para WPF). Por lo general, tengo una fuente de datos simulada de todos modos, por lo que es solo una cuestión de:

  • Agregar la declaración del espacio de nombres

    xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
  • Agregar el contexto de datos simulados a los recursos de control / ventana

    <UserControl.Resources>
      <ViewModels:MockXViewModel x:Key="DesignViewModel"/>
    </UserControl.Resources>
  • Configuración del contexto de datos en tiempo de diseño

    <Grid d:DataContext="{Binding Source={StaticResource DesignViewModel}}" ...

Funciona bastante bien.

Goran
fuente
2
Si tiene problemas de uso d:DataContext, puede encontrar ayuda en esta pregunta: stackoverflow.com/questions/8303803/…
Martin Liversage
27
¿No causaría este ejemplo que se cargue una instancia de MockXViewModel en sus recursos para una compilación de lanzamiento? ¿No es esto una preocupación?
jpierson
12
FYI: También necesita lo siguiente, o el compilador VS2012 no compilará el archivo xaml: xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"ymc:Ignorable="d"
Orion Edwards
51
jpierson tiene razón. Prefiero usar <Grid d:DataContext="{d:DesignInstance Type=ViewModels:MockXViewModel, IsDesignTimeCreatable=True}" .... De esta manera, el modelo de vista simulado solo se creará en el diseñador, no mientras se ejecuta la aplicación. Tenga en cuenta que este enfoque requiere que su modelo de vista simulada tenga un constructor sin parámetros. Pero lo mismo es el caso en el ejemplo dado anteriormente en la respuesta.
René
2
@ René tu enfoque es mucho mejor. Por favor agréguelo como respuesta y votaré por él
dss539
15

Como una amalgama de la respuesta aceptada de Goran y el excelente comentario de Rene.

  • Agregue la declaración del espacio de nombres. xmlns:d="http://schemas.microsoft.com/expression/blend/2008"

  • Haga referencia a su contexto de datos de tiempo de diseño desde el código.
    <Grid d:DataContext="{d:DesignInstance Type=ViewModels:MockXViewModel, IsDesignTimeCreatable=True}" ...

John Stritenberger
fuente
1
Estoy tentado de marcar esto como la nueva respuesta, pero tal vez podamos incluir el resto de los detalles.
el2iot2
Esto necesita más visibilidad, o debe incorporarse a la respuesta aceptada. Es una solución mucho mejor.
Lauraducky
¿Por qué es esto mejor? Al principio pensé que la respuesta aceptada produciría innecesariamente modelos simulados también en tiempo de ejecución, pero lo probé y, de hecho, no es así. Los recursos no se crean si no se utilizan.
Paul
@Paul Es realmente una cuestión de preferencia, pero esta respuesta mantiene todo el contexto de datos de tiempo de diseño en una declaración en lugar de tenerlo en dos lugares. Facilita los cambios
John Stritenberger
1
@JohnStritenberger No es solo una preferencia, la respuesta aceptada carga innecesariamente recursos en la memoria para siempre, no solo para el diseñador.
UuDdLrLrSs
4

Karl Shifflett describe un enfoque que debería funcionar igualmente bien para VS2008 y VS2010:

Visualización de datos de tiempo de diseño en Visual Studio 2008 Cider Designer en proyectos de WPF y Silverlight

Laurent Bugnion tiene un enfoque similar que se centra en Expression Blend. Se podría trabajar para VS2010, pero no han confirmado todavía.

Simular datos en modo de diseño en Microsoft Expression Blend

dthrasher
fuente
gracias por avisarme de esto. Me gusta el concepto DesignAndRunTimeDataContext.
el2iot2
1
Karl Shifflett tiene un artículo actualizado para Visual Studio 2010: Datos de muestra en WPF y Silverlight Designer
totorocat
1
La esencia del contenido del enlace realmente debería editarse en la respuesta, especialmente porque el primer enlace ahora está muerto.
Lauraducky
4

Quizás las nuevas funciones de tiempo de diseño de Visual Studio 2010 y Expression Blend 4 sean una opción para usted.

Cómo funciona se muestra en la aplicación de muestra BookLibrary de WPF Application Framework (WAF) . Descargue la versión .NET4.

jbe
fuente
Gracias por el enlace. ¿Hay un archivo de código en particular o una construcción que debería mirar para ver el enfoque? (una breve descripción sería genial)
el2iot2
Eche un vistazo al proyecto BookLibrary.Presentation. En este proyecto, encontrará la carpeta "DesignData" que utilizan UserControls en la carpeta "Vistas".
jbe
1
+1. Solo eché un vistazo a esto. Para cualquier persona interesada, el modelo de vista de datos de muestra se declara en XAML y se hace referencia a través de d: DataContext = "{d: DesignData Source = .. / DesignData / SampleLendToViewModel.xaml}"
RichardOD
4

Utilizo este enfoque para generar datos de tiempo de diseño con .NET 4.5 y Visual Studio 2013.

Solo tengo un ViewModel. El modelo de vista tiene una propiedad IsInDesignModeque dice si el modo de diseño está activo o no (ver clase ViewModelBase). Luego, puede configurar sus datos de tiempo de diseño (como llenar un control de elementos) en el constructor de modelos de vista.

Además, no cargaría datos reales en el constructor de modelos de vista, esto puede generar problemas en tiempo de ejecución, pero la configuración de datos para el tiempo de diseño no debería ser un problema.

public abstract class ViewModelBase
{
    public bool IsInDesignMode
    {
        get
        {
            return DesignerProperties.GetIsInDesignMode(new DependencyObject());
        }
    }
}

public class ExampleViewModel : ViewModelBase
{
    public ExampleViewModel()
    {
        if (IsInDesignMode == true)
        {
            LoadDesignTimeData();
        }
    }

    private void LoadDesignTimeData()
    {
        // Load design time data here
    }       
}
Martín
fuente
4

Usando Visual Studio 2017, he estado tratando de seguir todas las guías y preguntas como esta y todavía me enfrentaba a una <ItemsControl>que simplemente no ejecutó el código que tenía dentro del constructor de una DesignFooViewModelque hereda FooViewModel. Confirmé la parte "no se ejecutó" siguiendo esta guía "práctica" de MSDN (spoiler: MessageBoxdepuración). Si bien esto no está directamente relacionado con la pregunta original, espero que les ahorre mucho tiempo a otros.

Resulta que no estaba haciendo nada malo. El problema era que mi aplicación debía estar construida para x64. Como Visual Studio todavía es en 2018 un proceso de 32 bits y aparentemente no puede hacer girar un proceso de host de 64 bits para la parte del diseñador, no puede usar mis clases x64. Lo realmente malo es que no hay errores en ningún registro que se me ocurra.

Entonces, si se encuentra con esta pregunta porque está viendo datos falsos en su modelo de vista de tiempo de diseño (por ejemplo: <TextBlock Text="{Binding Name}"/>aparece Namesin importar que establezca la propiedad), es probable que la causa sea su compilación x64. Si no puede cambiar su configuración de compilación a anycpu o x86 debido a dependencias, considere la posibilidad de crear un nuevo proyecto que sea completamente anycpu y no tenga las dependencias (o ninguna dependencia). Por lo tanto, termina dividiendo la mayoría o todas las partes del código, excepto las de inicialización, de su proyecto "Aplicación WPF" en un proyecto de "biblioteca de clases C #".

Para la base de código en la que estoy trabajando, creo que esto forzará una separación saludable de preocupaciones a costa de cierta duplicación de código, lo que probablemente sea algo positivo.

joonas
fuente
3

Similar a la respuesta mejor calificada, pero mejor en mi opinión: puede crear una propiedad estática para devolver una instancia de datos de diseño y hacer referencia a ella directamente desde XAML así:

<d:UserControl.DataContext>
    <Binding Source="{x:Static designTimeNamespace:DesignTimeViewModels.MyViewModel}" />
</d:UserControl.DataContext>

Esto evita la necesidad de usar UserControl.Resources. Su propiedad estática puede funcionar como una fábrica que le permite construir tipos de datos no triviales; por ejemplo, si no tiene un ctor predeterminado, puede llamar a una fábrica o contenedor aquí para inyectar en las dependencias apropiadas.

Jack Ukleja
fuente