tutorial español curso c# wpf xaml mvvm architecture

c# - español - WPF MVVM ¿Por qué utilizar ContentControl+DataTemplate Views en lugar de vistas de ventana XAML rectas?



mvvm wpf (3)

Tengo una pregunta sobre MVVM en WPF que me está volviendo loco.

¿Por qué hacer algo como esto?

MainWindow.xaml:

<Window x:Class="MVVMProject.MainWindow" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"> <Grid> <ContentControl Content="{Binding}"/> </Grid> </Window>

Haga que su ExampleView.xaml se configure como:

<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:vms="clr-namespace:MVVMProject.ViewModels"> <DataTemplate DataType="{x:Type vms:ExampleVM}" > <Grid> <ActualContent/> </Grid> </DataTemplate> </ResourceDictionary>

Y crea la ventana así:

public partial class App : Application { protected override void OnStartup(StartupEventArgs e) { base.OnStartup(e); MainWindow app = new MainWindow(); ExampleVM context = new ExampleVM(); app.DataContext = context; app.Show(); } }

¿Cuándo puedes hacerlo así?

App.xaml: (Establecer la ventana de inicio / Vista)

<Application x:Class="MVVMProject.App" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" StartupUri="ExampleView.xaml"> </Application>

ExampleView.xaml: (una ventana no un ResourceDictionary)

<Window x:Class="MVVMProject.ExampleView" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:vms="clr-namespace:MVVMProject.ViewModels"> > <Window.DataContext> <vms:ExampleVM /> </Window.DataContext> <Grid> <ActualContent/> </Grid> </Window>

Esencialmente es "Ver como plantilla de datos" (VaD) vs. "Ver como ventana" (VaW)

Aquí está mi comprensión de la comparación: (Nota, utilizo VS 2008, así que me falta Blendability y / u otras cosas)

  • VaD: le permite cambiar Vistas sin cerrar la ventana. (Esto no es deseable para mi proyecto)
  • VaD: VM no sabe absolutamente nada sobre la Vista, mientras que en VaW (solo) tiene que ser capaz de crear una instancia al abrir otra ventana
  • VaW: realmente puedo ver mi xaml en el Diseñador (no puedo con VaD, al menos en mi configuración actual)
  • VaW: funciona intuitivamente con ventanas de apertura y cierre; cada ventana tiene (es) una vista correspondiente (y ViewModel)
  • VaD: ViewModel puede pasar a lo largo de ancho de ventana inicial, altura, resizabilidad, etc. a través de las propiedades (mientras que en VaW se establecen directamente en la ventana)
  • VaW: puede configurar FocusManager.FocusedElement (no estoy seguro de cómo en VaD)
  • VaW: Menos archivos, ya que mis tipos de ventana (por ejemplo, Ribbon, Dialog) están incorporados en sus Vistas

Entonces, ¿qué está pasando aquí? ¿No puedo simplemente construir mis ventanas en XAML, acceder a sus datos limpiamente a través de las propiedades de la máquina virtual y terminar con eso? El código subyacente es el mismo (prácticamente nulo). Estoy luchando por entender por qué debería barajar todas las cosas de View en ResourceDictionary. (Pero no quiero hacerlo mal ;-))

¿Incluso importa? ¿Hay algo que me he perdido? Muchas gracias por leer. : O

Gracias a Rachel Lim y Nick Polyak por mi comprensión floreciente de MVVM

Editar: cambio de flujo menor


Dado que en VaD los modelos de vista no saben nada sobre las vistas, puede crear una aplicación totalmente funcional compuesta únicamente por modelos de vista y sin vistas. Esto conduce a la posibilidad de escribir una aplicación que puede manejarse completamente por código. Esto a su vez conduce a la posibilidad de realizar pruebas de integración sin la GUI. Las pruebas de integración a través de la GUI son notoriamente frágiles, mientras que las pruebas a través de modelos de vista deberían ser más robustas.


Desde mi experiencia personal: ambos modelos de trabajo son aviables, dependiendo de lo que desee y según los requisitos de la aplicación. La idea detrás de VaD es decopular el contenido y el contenedor. Si implementa VaD , puede usar esta plantilla (de forma predeterminada) cada vez que muestre algún elemento de este tipo. Puede usarlo en ItemsControls (listas, listas de vista, cuadrículas, etc.) y en ContentControls solo para hacer enlaces. Como dijiste, VaD funciona para cambiar el contenido de la ventana sin cerrar y abrir una nueva. También puede definir la vista usando UserControls , luego toma el control de los elementos enfocados y también puede administrar el código detrás. Entonces, su plantilla de datos puede ser así:

<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:vms="clr-namespace:MVVMProject.ViewModels"> <DataTemplate DataType="{x:Type vms:ExampleVM}" > <CustomUserControl A="{Binding A}" B="{Binding B}" DataContext="{Binding}" .../> </DataTemplate>

También en un UserControl puede establecer propiedades de dependencia, eso facilita el trabajo, ya que permite enlaces y desacoplamiento de la aplicación.

Pero, por supuesto, si su aplicación no requiere el cambio de contenido dinámicamente, está bien usar VaW para la ventana principal o cualquier otra ventana. De hecho, puede usar tanto VaW como VaW . Este último se puede usar para elementos internos en la aplicación, que no requiere ventanas. Explica qué es mejor para ti, según los requisitos de la aplicación y el tiempo disponible para desarrollar la aplicación. Espero que esta experiencia personal ayude ...


Las personas usan DataTemplates esa manera cuando quieren cambiar dinámicamente las Vistas en función del Modelo de Vista:

<Window> <Window.Resources> <DataTemplate DataType="{x:Type local:VM1}"> <!-- View 1 Here --> </DataTemplate> <DataTemplate DataType="{x:Type local:VM2}"> <!-- View 2 here --> </DataTemplate> </Window.Resources> <ContentPresenter Content="{Binding}"/> </Window>

Asi que,

si Window.DataContext es una instancia de VM1 , entonces se mostrará View1 ,

y si

Window.DataContext es una instancia de VM2 , luego se mostrará View2 .

De acuerdo, no tiene ningún sentido si solo se espera 1 Vista, y nunca cambiada.

Espero que esto sea lo suficientemente claro: P