tutorial español c# wpf xaml mvvm

c# - español - ¿Cómo especifico el tipo de DataContext(ViewModel) para obtener la comprobación del enlace en tiempo de diseño en el editor XAML sin crear un objeto ViewModel?



mvvm wpf (1)

Esta pregunta ya tiene una respuesta aquí:

Puedo especificar DataContext así:

<Window ... > <Window.DataContext> <MainViewModel /> </Window.DataContext> ... </Window>

Y en este caso, WPF creará un objeto de tipo MainViewModel y lo asignará a la propiedad DataContext de la ventana (esto sucede dentro del método InitializeComponent() Window).

Pero, ¿qué ViewModel si mi ViewModel no tiene un constructor predeterminado? O qué sucede si quiero inicializar ViewModel y asignarlo a DataContext después de que Window.InitializeComponent() se ejecuta (dentro del constructor de Windows o desde el mismo código que ejemplifica la ventana) - en este caso WPF crea un ViewModel (dentro de InitializeComponent() ), lo asigna al DataContext de la ventana y luego lo sobrescribo con otra instancia de ViewModel (estoy preocupado por la creación de instancias de objetos innecesarios aquí).

Me gustaría poder especificar solo un tipo de ViewModel , por lo que recibiría una advertencia de tiempo de diseño si ViewModel mal el nombre de una propiedad dentro de {Binding} (o después de renombrar la propiedad), o podría ir a Declaration haciendo clic en ( XAML) en un nombre de propiedad dentro {Binding PropertyName}.

Gracias por tu tiempo invaluable.


Esa es la parte difícil si haces el MVVM hágalo tú mismo.

Tus opciones, básicamente:

Use Inyección de Dependencia

Puede inyectar ViewModel en el constructor de su Page / Window y asignarlo dentro de él.

Sin embargo, esto tiene algunas desventajas.

  • más difícil de usar modelos de vista en tiempo de diseño
  • Las vistas ya no se pueden instanciar desde XAML

ViewModel First con servicio de navegación

Resolvería sus ViewModels y realizaría toda su navegación a través de un servicio de navegación. En sus ViewModels pasa el servicio INavigationService . Puede navegar a una vista usando el tipo de modelo de vista. Dentro, crea una instancia del ViewModel mediante Dependency Injection, luego crea una instancia de View (basado en convenciones de nomenclatura o vía configuración DI)

Eso es un poco mejor, pero aún no le permitirá crear una instancia de las Vistas dentro de XAML. La gran ventaja es que le permite pasar fácilmente parámetros al ViewModel (teniendo ViewModels implementando la propiedad INavigationAware con el método NavigatedTo , que se llama después de la creación de instancias y pasando el parámetro a)

ViewModelLocator / Propiedad / Comportamiento adjunto

Con este, crearía una propiedad adjunta, que puede establecer en true (es decir, autoarrancar) o en un tipo de modelo de vista (para tener más control sobre el modelo de vista instanciado) y buscar, resolver el modelo de vista y asignarlo.

Básicamente brinda todas las ventajas anteriores más la forma de instanciación Vista.

El último es básicamente lo que hace MVVM Framework de Microsoft "Prism" (servicio de navigationService.Navigate("MyPage", myParameterForViewModel) , instanciación de DataContext y asignación de XAML a través de autowireing (en XAML: prism:ViewModelLocator.AutoWireViewModel="True" ).

Dicho esto, es mejor utilizar un MVVM Framework madurado que haga estas partes de su cableado (incluso si decide no usar las clases base como BindableBase o como se llame en dicho marco).

En cuanto al tiempo de diseño ViewModel / auto-completition para ViewModels:

Puede usar los atributos de tiempo de diseño de Blend para hacer esto. Primero debe agregar las referencias de conjunto de mezcla. Luego puede agregar xmlns:d="http://schemas.microsoft.com/expression/blend/2008" espacio de nombres en su página / vista.

Luego puede vincularlo en su página mediante d:DataContext="{d:DesignInstance my:DesignTimeViewModel, IsDesignTimeCreatable=True} . Observe la d: antes del DataContext, esto es importante. Este DataContext solo se usará en el Diseñador (Visual Studio XAML Designer o en Blend). Esto es para evitar interferir con el DataContext normal (sin el prefijo).

Ejemplo:

<Window x:Class="WpfApplication1.Window2" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:myApp="clr-namespace:WpfApplication1" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" mc:Ignorable="d" d:DataContext="{d:DesignInstance myApp:Window2ViewModel, IsDesignTimeCreatable=True}"> <Grid> <TextBlock Text ="{Binding Test}"/> </Grid> </Window>

Si utiliza interfaces para sus ViewModels, es bastante rápido crear la instancia de diseño, simplemente haciendo que Visual Studio implemente toda la propiedad Interface y le proporcione algunos valores predeterminados (para la propiedad, de modo que tenga datos de ejemplo en su ViewModel para verificar que las vinculaciones funcionen correctamente) .

Esto requiere que cree ViewModels separados en tiempo de diseño y sus ViewModels reales, que no es tan malo como suena. Esto le da a su diseñador de UI la oportunidad de trabajar con él, incluso si el modelo de vista real no se ha terminado / implementado aún.