¿Es una buena práctica usar controles de usuario para estructurar formularios WPF incluso si estos controles de usuario solo se usan una vez?

8

Desarrollo una aplicación WPF usando MVVM y estoy aprendiendo cómo hacer las cosas mejor.

Tengo un formulario WPF con selectores, dos listas con campos de búsqueda y algunos otros elementos. Actualmente todo está en una forma y funciona. Pero ahora la VM para esa forma tiene más de 800 líneas y aún no está terminada.

Quiero estructurar mejor este formulario y el código. Pensé en regiones, archivos con clases parciales y controles de usuario. Creo que los controles de usuario serían mejores porque encapsulan un par de controles y lógica. Si usara los controles de usuario, la cantidad de código en esa ventana y VM se reduciría drásticamente.

Para hacerlo correctamente, trabajo en el libro "Pro WPF 4.5 en C # 4th Edition", Capítulo 18 - Elementos personalizados y la muestra ColorPickerUserControl. La muestra trata sobre un selector de color con tres controles deslizantes y tiene 150 líneas de código.

Creo que entiendo cómo funciona, pero me parece que crear controles de usuario, incluso con una funcionalidad muy limitada como en esa muestra, es mucho trabajo . Si usara estos controles varias veces, entonces entiendo que tendría sentido hacerlo. Pero si uso los controles solo una vez y hago esto solo para estructurar mi forma, entonces esto parece ser mucho trabajo con poca ganancia.

Mi pregunta es: ¿Es una buena práctica usar controles de usuario para estructurar formularios incluso si estos controles de usuario solo se usan una vez? Si no, ¿hay una mejor alternativa?

Editar (no es necesario leer, solo más información): hasta ahora no escribí ningún detalle porque quería aprender sobre el principio, pero después de leer la interesante respuesta de 17 de 26, aquí hay algunos detalles: Este formulario es para seleccionar títulos de música.

  • Grupo A: (posible control de usuario A) se trata del tipo de selección, como seleccionar por artista o álbum, con o sin video, tal vez año de publicación, etc.

  • Grupo B: esta lista contiene nombres de artistas que se filtran de acuerdo con los criterios de A. El usuario puede filtrar la lista, es decir, mostrar solo los nombres de artistas que contienen "top".

  • Grupo C: esta lista muestra los títulos del artista seleccionado en B que también utilizan criterios de A (es decir, audio o video). Se puede filtrar de manera similar a B, es decir, solo títulos que contengan "usted".

La mayor parte de la lógica ocurre en la VM (DataContext del formulario). Las listas de A y B provienen de una base de datos. Las listas se filtran y se preparan para su presentación (es decir, múltiples títulos con el mismo nombre pero en álbumes diferentes). El usuario selecciona un título en la Lista C haciendo doble clic o arrastrando y soltando en otro formulario WPF.

Lo que quiero: quiero un código legible para poder modificarlo fácilmente. Si quiero agregar, es decir, otro filtro, digamos que solo muestre artistas femeninas, sería bueno si pudiera ir al control de usuario A y agregar casillas de verificación para artistas masculinos y / o femeninos.

El XAML en la forma actual no es un problema, está bien estructurado. Pero la VM tiene código para todo lo anterior. Algunas cosas están en el constructor, algunas en la sección de comandos, algunas propiedades y campos de respaldo. Todavía puedo encontrar cosas ahora, pero creo que sería mejor si el código estuviera más estructurado. Por eso pienso en los controles de usuario.

Intento seguir MVVM porque creo que la lógica detrás de esto tiene mucho sentido. Pero no soy un seguidor fanático de ninguna práctica teórica. Es decir, si puedo hacer algo en 5 líneas de CodeBehind o en 50 líneas en la VM, lo haré probablemente en CodeBehind. Mi pregunta es sobre el principio de cómo crear formularios estructurados en WPF. El formulario que describo anteriormente es un buen ejemplo, pero la respuesta no debe concentrarse en este solo, sino en la idea de cómo estructurar formularios WPF, es decir, con (o sin) controles de usuario.

Acerca de por qué creo que los controles de usuario requieren mucho trabajo: tienen propiedades de dependencia, eventos enrutados, etc. Todo esto me parece mucho más complicado que las propiedades "normales" con campos de respaldo e INotify. Pero tal vez solo tenga que acostumbrarme a las propiedades de dependencia, eventos enrutados, etc.

Edgar
fuente
Estoy un poco desconcertado de por qué crees que hacer controles de usuario es mucho trabajo. En su forma más simple, un UserControl es solo un contenedor. Haces una como esta: <UserControl> </UserControl>. Eso es.
Robert Harvey
Con respecto a su edición: los controles de usuario solo tienen propiedades de dependencia, eventos enrutados, etc., si decide colocar esas cosas. No son obligatorias, de ninguna manera.
Robert Harvey
@RobertHarvey: Sí, lo entiendo. Pero parece una "funcionalidad completa" con enlace bidireccional, que activa algo en la forma principal si algo en el control del usuario fue cambiado, etc., son necesarios. Creo que la muestra en el libro que menciono anteriormente muestra cuán necesarios son a menudo (no siempre).
Edgar
¿No tendrías que hacer todo eso sin usar los controles de usuario?
Robert Harvey
1
Tampoco parece que ViewModel esté haciendo mucho. Ordenar y filtrar una lista de resultados es una tarea bastante pequeña para un ViewModel. Quizás el problema no sea lo que está haciendo la VM, sino cómo está escrito. Quizás hay algunas características de C # que puede usar para reducir el tamaño del código. O tal vez la VM se puede refactorizar para reducir su tamaño.
17 de 26

Respuestas:

7

Absolutamente sí. Es una buena idea de la misma manera que es una buena idea aplicar la separación de preocupaciones en las clases para poner cada una por separado para realizar una sola tarea. Puede que solo tenga una instancia de esa clase, pero no importa. La optimización no es en términos de rendimiento del programa sino en términos de organización y "salud" general del programa.

Desea poder volver a su programa un día y no tener que desplazarse a través de varios cientos de páginas de código, incluso si se coloca en regiones (usar regiones en clases con mucho código es como poner lápiz labial en un cerdo, por el camino). Si algún día decides usarlo en otro lugar, puedes hacerlo con gracia y sin muchos problemas.

Simplemente no caigas en la tentación de darle al usuario acceso de control al formulario principal. Si lo hace de esta manera, use eventos para transmitir información al padre, con el formulario padre como suscriptor.

Neil
fuente
Además, cuando crea un control personalizado, puede encapsular la parte de la lógica de presentación de la que es responsable, lo que, si se hace correctamente, hará que su lógica de presentación en el control que lo contiene sea más simple.
Filip Milovanović
"Absolutamente sí" no es una buena respuesta en mi humilde opinión cuando el esfuerzo para crear un control de usuario es tan alto como lo describe el OP.
Doc Brown
1
Un VIewModel tiene la única preocupación de coordinar la lógica de la interfaz de usuario para un conjunto de controles de interfaz de usuario. Romperlos puede ser un desafío y, a menudo, no tiene sentido.
17 de 26
2
@DocBrown La pregunta pide opiniones sobre la práctica en general. Así que creo que la respuesta de Neil es justa y una opinión honesta. No hay una respuesta absoluta para nada, pero siempre podemos recomendar un lugar para comenzar. En mi humilde opinión, si me pagaran por codificarlo, lo haría de la manera correcta (recomendación de Neil). Además, realmente podría ayudar hacer esto si alguna vez desea reutilizar los controles en proyectos futuros. Pero si solo quiero jugar o hacerme algo, lo haría de la manera más rápida porque ya estoy atrasado en mi ropa.
Christopher
1
"absolutamente sí" es incorrecto. La respuesta correcta es "depende". Agrega costo y complejidad para dividir una Vista / VM en múltiples Vistas / VM. El beneficio debe superar el costo.
17 de 26
4

Esta es una pregunta realmente difícil de responder sin ver el código real. También estás mezclando términos un poco. Los controles de usuario no son un mapeo 1: 1 con ViewModels.

Los controles de usuario tienen un propósito específico en la vida: son una composición de múltiples elementos de la interfaz de usuario que se utilizan juntos como una unidad. Los controles de usuario son subsecciones de una vista. Esto es muy diferente de un ViewModel, que contiene la lógica a la que está vinculada una Vista.

Tal vez tenga sentido dividir su XAML en múltiples controles de usuario, todo impulsado por un solo ViewModel. Tal vez tenga sentido dividir su código XAML y C # en múltiples pares View-VM. Tal vez tenga sentido dejarlo como lo tiene ahora. Imposible decirlo sin ver el código en cuestión.

¿Cuál es tu objetivo final aquí? ¿El tamaño del código le causa dolor real o es solo para seguir alguna práctica teórica?

¿Está tratando de reducir el tamaño de sus Vistas XAML o el tamaño de sus C # ViewModels? Estas son dos tareas muy diferentes en el mundo WPF MVVM.

800 líneas no son terriblemente grandes para una máquina virtual que respalda una interfaz de usuario que tiene algún tipo de complejidad. Romper una VM a menudo puede causar más problemas de los que resuelve. ViewModels toma decisiones como "deshabilitar esta función cuando esta otra lista está vacía". Intentar dividir ese tipo de toma de decisiones en múltiples componentes a menudo no tiene sentido y solo agregará complejidad al código.

Ahora con eso dicho, puede haber trabajo que está haciendo en la máquina virtual que no tiene nada que ver con su lógica ViewModel y puede dividirse fácilmente en su propia clase. Esto reduciría el tamaño del ViewModel sin aumentar la complejidad general del código.

Supongo que fue una forma muy larga de decir "depende, y no podemos saberlo sin ver el código en cuestión".

17 de 26
fuente
Gracias por tu respuesta. Nunca leí acerca de tener múltiples pares View-VM, eso suena como una idea interesante. Por lo demás, lo agregué a mi pregunta.
Edgar
¿Qué es View en este par de View-VM múltiple(a UserControl/a Grid/a Page ??)
Nombre de código Jack
0

Si yo, que no sé nada sobre su aplicación, tuviera que agregar un nuevo campo sobre el campo del apellido, o cambiar el orden de algunos campos ... ¿Me resultaría fácil o desalentador?

No confío en las regiones porque el compilador no verificará si extravía algo en la región incorrecta

Debe desarrollar software con el objetivo de facilitar que las personas construyan sobre lo que creó.

Un bravo dev
fuente
¿Alguna vez creaste un formulario en WPF? En caso afirmativo, debe saber que haría lo que describe en la parte XAML del formulario y no en el código subyacente o VM. O para responder a su pregunta: Sí, sería muy fácil.
Edgar
@Edgar Mi culpa. Usted habló sobre componentes visuales y controles de usuario y pensé que eso era todo. Si todas sus imágenes están en la vista, y toda su lógica de negocios en el modelo, no debe preocuparse por tener una VM larga.
A Bravo Dev