.net - Wpf UserControl y MVVM
user-controls dependency-properties (3)
Estoy pensando en escribir un control de usuario de WPF para mi aplicación. Estoy usando MVVM en mi aplicación.
El control del usuario puede requerir propiedades de dependencia que pueden configurarse en mi vista principal. cuando se usa MVVM, la idea es que la Vista principal eventualmente creará un enlace entre los UserControls
DP con la VM de Parent View)
Dependency Properties
deben crearse en la clase de vista, ya que las máquinas virtuales no heredan de DependencyObject
. Esto significa agregar código dentro del código XAML detrás.
Me preguntaba si podría dar consejos sobre cómo debería diseñar un control de usuario al desarrollar una aplicación WPF utilizando MVVM ...
Básicamente, en lugar de vincular el espacio de datos de su UserControl al userControlViewModel, es mejor hacerlo en el primer elemento secundario del control de usuario. De esa manera, todas las referencias que realice dentro del control se vincularán al userControlViewModel, pero las propiedades de las dependencias se pueden establecer desde el conjunto de contexto de datos donde desea utilizar su UserControl.
Este patrón me ha funcionado bastante bien, en su UserControl 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
Un UserControl
es parte de la "Vista" en "MVVM" al igual que los controles TextBox
o ListView
son parte de la Vista.
Ya sea que decida utilizar MVVM para desarrollar su UserControl
o escribirlo en QBASIC (no recomendado), no rompe el patrón de MVVM para los consumidores de su UserControl
siempre que puedan hacer todo lo que necesiten con UserControl
vinculando a DependencyProperty
Está expuesto en su UserControl
. es decir, su UserControl
debe exponer las propiedades de las que depende (de ahí el nombre). Una vez que comprenda esta DependencyProperty
, de repente tendrá mucho sentido y querrá que sean útiles en los controladores de eventos modificados y en los valores predeterminados que especifique en su constructor.
Si su UserControl
está en un ensamblaje diferente o no, no puedo ver cómo eso hace una diferencia.
Dicho esto, muchos recomendarían que construyas UserControl
usando el patrón MVVM por todas las buenas razones que MVVM trae, por ejemplo, ayudando a otro desarrollador a observar tu código. Sin embargo, algunas cosas simplemente no son posibles y / o mucho más difíciles, más complejas y menos eficientes. Para piratear el XAML, no estoy hablando de su formulario de usuario de la variedad de jardín, sino, por ejemplo, un UserControl
maneja el diseño de miles de imágenes. Además, como está trabajando en su Vista, ¡ NO quiere que los ViewModels de UserControl
mezclen con sus aplicaciones!
Básicamente, estoy diciendo que está bien dentro de MVVM ¡no usar MVVM en tu Vista!
Caso 1: Si está creando este control solo para ser consumido en su aplicación, entonces puede seguir adelante y crear un ViewModel
para él, pero no necesita crear DP, su ViewModel
solo puede implementar INotifyPropertyChanged
y su Vm principal puede Todavía se unen a ellos.
En nuestro caso, para los controles de usuario hemos creado ParentVM
separadas y una instancia de ellas estaba presente en ParentVM
. Por lo tanto, la vista principal tendrá este control y vinculará el UserControlVM
a este control ( ParentVM.UserControlVM
) y usercontrol se encargará de otros enlaces.
Caso 2: Si otras aplicaciones / desarrolladores utilizarán su control y no desea que sea sencillo, siga adelante con la creación de controles personalizados después de la implementación de la plantilla de control. De esta manera, puede crear controles sin look y usar dependency properties
también. Además, quienquiera que use ese control no necesita saber sobre el modelo de vista relacionado y utilizarlo.
Algunas de las preguntas / mensajes similares:
Pregunta de diseño de WPF (control personalizado o mvvm): pregunta de diseño de WPF (control personalizado o mvvm)
Control personalizado en WPF usando el concepto MVVM: http://social.msdn.microsoft.com/Forums/en-US/wpf/thread/6293b176-e1e9-4610-af49-d53e6d294969/
WPF User Control hell con MVVM y propiedades de dependencia: WPF User Control hell con MVVM y propiedades de dependencia