2011-12-12 6 views
23

Estoy atando un cuadro de texto a un objeto, así:Cómo usar d: DesignInstance con tipos que no tienen un constructor predeterminado?

<TextBlock d:DataContext="{d:DesignInstance ViewModel:TaskVM }" 
      Text="{Binding Title}" MouseLeftButtonDown="TextBlock_MouseLeftButtonDown"> 
    </TextBlock> 

Ahora me pregunto cómo hacer que mostrar los datos simulados durante el diseño. He intentado hacer algo así:

<TextBlock Text="{Binding Path=Title}" MouseLeftButtonDown="TextBlock_MouseLeftButtonDown"> 
    <d:DesignProperties.DataContext> 
     <ViewModel:TaskVM Title="Mock"/> 
    </d:DesignProperties.DataContext> 
    </TextBlock> 

Sin embargo, ya que no tiene TaskVM ctor defecto, me estoy haciendo un "No constructor por defecto" que se encuentra.

Sé que cuando uso d:DataContext="{d:DesignInstance ViewModel:TaskVM }" crea un tipo de datos simulado. ¿Hay alguna manera de establecer las propiedades de este tipo de simulacro?

Gracias!

Respuesta

37

El constructor predeterminado es necesario para crear un tipo de instancia en XAML. Como solución, puede crear simplemente una subclase de TaskVM que tendrá el contructor predeterminado y usarlo como un contexto de datos de tiempo de diseño.

<TextBlock d:DataContext="{d:DesignInstance ViewModel:DesignTimeTaskVM }" 
      Text="{Binding Title}" MouseLeftButtonDown="TextBlock_MouseLeftButtonDown"> 
</TextBlock> 

Otra alternativa es fijar d:IsDesignTimeCreatable a False y se creará un tipo de sustituto para que en tiempo de ejecución (utilizando el tipo de TaskVM como una "forma").

<TextBlock d:DataContext="{d:DesignInstance ViewModel:DesignTimeTaskVM, IsDesignTimeCreatable=False}" 
      Text="{Binding Title}" MouseLeftButtonDown="TextBlock_MouseLeftButtonDown"> 
</TextBlock> 
+0

Me gusta esa idea :). La herencia me permitirá omitir la recreación de todas las propiedades. Todavía preferiría que hubiera una forma incorporada de manipular el objeto simulado creado por WPF. SÍ crea un objeto simulado, ¿no? Dice en la documentación de MSDN: d: IsDesignTimeCreatable \t En la extensión de marcado d: DesignInstance, especifica que la instancia de diseño se crea a partir de su tipo, en lugar de un tipo sustituto generado por el diseñador. – VitalyB

+0

@VitalyB - Sí, tienes razón.Parece que puede establecer 'd: IsDesignTimeCreatable' en' False' y se creará un tipo sustituto para usted en tiempo de ejecución (utilizando su tipo TaskVM como una "forma"). –

+1

Exactamente. Lo cual es bastante desalentador ya que no puedo establecer propiedades de ese tipo sustituto. – VitalyB

3

Puede agregar un constructor predeterminado a su máquina virtual. Luego podría verificar si está en tiempo de diseño y establecer valores de tiempo de diseño apropiados para sus propiedades.

+12

Otra opción es crear un constructor predeterminado y marcarlo con '[Obsoleto (" use only for design mode ", True)]' por lo que se genera un error de compilación si intenta usarlo. – DonkeyMaster

+0

El enlace está muerto. Se refiere a esta pregunta: https://stackoverflow.com/q/834283/200443 – Maxence

2

Otra alternativa sería usar una clase estática para contener el modelo de vista y llamar a esa clase desde el XAML. Aquí se muestra un ejemplo:

El xaml utiliza una fábrica de vista del modelo para crear el contexto de datos de diseño:

xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
mc:Ignorable="d" 
d:DataContext="{x:Static local:ViewModelFactory.ViewModel}" 


El ViewModelFactory estática construye el modelo de vista en su constructor y lo almacena en una propiedad pública donde se puede acceder desde el exterior (desde el XAML):

public static class ViewModelFactory 
{ 
    /// <summary> 
    /// Static constructor. 
    /// </summary> 
    static ViewModelFactory() 
    { 
     ViewModel = new TypeOfViewModel(null); 

     // further configuration of ViewModel 
    } 

    public static TypeOfViewModel ViewModel 
    { 
     get; set; 
    } 
} 



Atención: t La clase TypeOfViewModel no tiene un constructor sin parámetros. Por lo tanto, ViewModelFactory tiene que pasar algún valor, en este caso null.

Por lo tanto, en este caso, la clase TypeOfViewModel debería implementarse de manera que sea consciente de que, durante el tiempo de diseño, la dependencia pasada es nula.

public class TypeOfViewModel 
{ 
    /// <summary> 
    /// Constructor. 
    /// </summary> 
    /// <param name="dependency">May be null at design time</param> 
    public TypeOfViewModel(SomeDependentClass dependency) 
    { 

    } 
} 
Cuestiones relacionadas