2010-07-26 19 views
18

Estoy pensando en escribir un control de usuario WPF para mi aplicación. Estoy usando MVVM en mi aplicación.Wpf UserControl y MVVM

El control del usuario puede requerir Propiedades de dependencia que se pueden establecer en mi Vista principal. al usar MVVM, la idea es que la perspectiva de los padres con el tiempo crear una vinculación entre el UserControls DP con los padres de Vista VM)

Dependency Properties necesidad de crear en la clase Ver como VM no heredar de DependencyObject. Esto significa agregar código dentro del código XAML detrás.

Me preguntaba si se puede dar consejo en cuanto a cómo debería diseñar un control de usuario en el desarrollo de aplicaciones WPF usando MVVM ...

Respuesta

24

Caso 1: Si va a crear este control sólo para ser consumida en su aplicación entonces puede continuar y crear un ViewModel para ello, pero luego no necesita crear DP, su ViewModel puede implementar INotifyPropertyChanged y su Vm padre aún puede vincularse a ellos.

En nuestro caso, para los controles de usuario hemos creado máquinas virtuales separadas y una instancia de la misma estaba presente en ParentVM. Así que la vista padre tendrá este control en ella y vinculará el UserControlVM a este control (ParentVM.UserControlVM) y usercontrol se ocupará de otras vinculaciones.

Caso 2: Si su control será utilizado por otras aplicaciones/desarrolladores y no desea mantenerlo simple, siga adelante con la creación de controles personalizados siguiendo la implementación de la plantilla de control. De esta forma puede crear controles sin fallas y también usar dependency properties. Además, quien usa ese control no necesita conocer el modelo de vista relacionado y usarlo.

algunas de las preguntas similares/mensajes:

WPF cuestión de diseño (control personalizado o MVVM): WPF design question (custom control or mvvm)

de control personalizado en WPF usando MVVM concepto: http://social.msdn.microsoft.com/Forums/en-US/wpf/thread/6293b176-e1e9-4610-af49-d53e6d294969/

Infierno de control de usuario de WPF con MVVM y Propiedades de dependencia: WPF User Control hell with MVVM and Dependency Properties

+0

hi akjoshi, lo startegy usas para obligar a los padres VM a los controles de propiedad VM? ¿Podría dar un pequeño ejemplo? – byte

+1

Genralmente configuré el DataContext del control secundario al objeto de UserCOntrolVM que está presente en ParentVM. así que supongamos que tiene una ventana principal dentro de la cual su control de usuario está presente. Ahora, el contexto de datos de la ventana principal está configurado como ParentVM, este ParentVM expondrá una propiedad de tipo UserControlVM. Ahora solo tenemos que establecer el contexto de datos del control de usuario así: akjoshi

+0

Gracias akjoshi, utilizo esta estrategia en mi aplicación y todas las VM implementan INotifyPropertyChanged. Mi pregunta era más sobre la vinculación de propiedades en su comentario "su ViewModel puede implementar INotifyPropertyChanged y su Vm padre aún puede vincularse a ellos". ¿Creas la VM de controles en ParentVM y dejas que ParentVM se enlace directamente a la VM de controles? – byte

7

Un UserControl es parte de la "Vista" en "MVVM" al igual que los TextBox o ListView controles son parte de la vista.

Ya sea que decida usar MVVM para desarrollar su UserControl sí mismo o escribirlo en QBASIC (no se recomienda) no se rompe el patrón MVVM para los consumidores de su UserControl tanto tiempo, ya que pueden hacer todo lo que necesitan con su UserControl vinculando a DependencyProperty expuesto en su UserControl. es decir, su UserControl debe exponer las propiedades en las que está dependiente (de ahí el nombre). Una vez que comprenda esto, DependencyProperty de repente tiene mucho sentido y desea que sean útiles en los manejadores de eventos modificados y los valores predeterminados que especifique en su constructor.

Si su UserControl está en un ensamblaje diferente o no, no puedo ver cómo eso marca la diferencia.

Dicho esto, muchos recomendarían que construyes tu UserControl utilizando el propio patrón MVVM por todas las buenas razones que MVVM aporta, p. ayudando a otro desarrollador a mirar tu código Sin embargo, algunas cosas simplemente no son posibles y/o mucho más difícil y complejo piratear el XAML para hacer esto - no estoy hablando de su variedad de jardín Agregar formulario de usuario, pero por ejemplo un UserControl manejando el diseño de miles de imágenes. Además, dado que está trabajando en su Vista, lo hace NO quiere que su ViewModels UserControl se mezcle con sus aplicaciones.

Básicamente, estoy diciendo que MVVM no utiliza MVVM en su vista.

+1

Le he subido la apuesta porque era una buena respuesta, pero también porque quería ser quien hizo que su puntaje de 4444 fuera 4454 bwahah –

+1

Una buena recomendación para mantener las máquinas virtuales de la aplicación y 'UserControl' separadas (+1). –

0

Básicamente, en lugar de vincular el contexto de datos de UserControl al userControlViewModel, es mejor hacerlo en el primer elemento secundario del control de usuario. De esta forma, todas las referencias que realice dentro del control estarán vinculadas a userControlViewModel, pero las propiedades de las dependencias se pueden configurar desde el contexto de datos en el que desea usar UserControl.

Este modelo ha funcionado bastante bien para mí, en el control de usuario XAML:

<UserControl x:Class="Six_Barca_Main_Interface.MyUserControl" 
      xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
      xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
      xmlns:local="clr-namespace:Six_Barca_Main_Interface" 
      xmlns:System="clr-namespace:System;assembly=mscorlib" 
      mc:Ignorable="d" 
      d:DesignHeight="900" d:DesignWidth="900"> 

    <DockPanel x:Name="rootDock" > 
     <TextBlock>{Binding SomethingInMyUserControlViewModel}</TabControl> 
    </DockPanel> 
</UserControl> 

Luego, en el código detrás:

public partial class MyUserControl : UserControl 
{ 
    UserControlViewModel _vm; 

    public MyUserControl() 
    { 
     InitializeComponent(); 

     //internal viewModel set to the first child of MyUserControl 
     rootDock.DataContext = new UserControlViewModel(); 

     _vm = (UserControlViewModel)rootDock.DataContext; 


     //sets control to be able to use the viewmodel elements 

    } 

    #region Dependency properties 
    public string textSetFromApplication 
    { 
     get{return (string)GetValue(textSetFromApplicationProperty);} 
     set{SetValue(textSetFromApplicationProperty, value);} 
    } 

    public static readonly DependencyProperty textSetFromApplicationProperty = DependencyProperty.Register("textSetFromApplication", typeof(string), typeof(MyUserControl), new PropertyMetadata(null, OnDependencyPropertyChanged)); 

    private static void OnDependencyPropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) 
    { 
     ((MyUserControl)d)._vm.SomethingInMyUserControlViewModel = 
      e.NewValue as string; 
    } 
#endregion