Descargo de responsabilidad: En esta pestaña de preguntas, página, un diálogo realmente significa lo mismo, lo siento. Mi excusa: no estoy seguro de cómo debería ser el producto final: un montón de ventanas separadas o todo en uno.Buscando un gran ejemplo de asistente implementado con WinForms y/o un diseño de aviso de registro
Estoy buscando mejorar un Wizard existente y difícil de mantener preparado con WinForms. Necesito tratar de mantener el aspecto y la sensación sobre lo mismo, pero necesito limpiar la lógica interna. Hay 5 cuadros de diálogo en total, todos los cuales se muestran uno tras otro (después de que se hace clic en el botón Siguiente, por supuesto) dentro de un método gigante. La forma de saltar hacia adelante y hacia atrás es con ... ¡5 o 6 etiquetas y GOTO!
Ahora, este asistente es lineal, no es un árbol. Desde cualquier diálogo/página, debería poder ir a, como máximo, otros dos. De alguna manera, la lista doblemente enlazada viene a la mente. En este momento hay 5 * 4 = 20
transiciones de estado potencial, mientras que solo 2*1 + 3*2 = 8
de ellas son válidas. No tengo que usar goto
s. Por lo general son malvados, y en este caso lo son, es difícil mantener esto ya ... y estoy pensando en agregar otra, 6ª página. La razón por la cual goto
están ahí es muy probable porque A) la presión del tiempo cuando se estaba realizando la v. 1.0, B) Fue hace 5 años, por lo que los mejores ejemplos/tutoriales sobre asistentes disponibles en ese momento pueden no haber sido excelentes.
Ahora, la mayoría de las páginas del asistente solicitan la entrada del usuario. Las páginas siguientes se representan según lo que haya ingresado el usuario. Si el usuario dice en la página 3 y decidió volver a poner un botón de retroceso en 1, y no ha cambiado nada, y pulsa Siguiente dos veces, el estado no debería cambiar. Sin embargo, cambiar las cosas en la página x generalmente invalidará las cosas en las páginas x + 1 y posteriores. Sin embargo, existen excepciones, ya que algunas o todas las configuraciones en una página x pueden depender de la página x-1, x-2, etc., pero las páginas x + 1, x + 2, etc. no dependen de esa x para algo x.
Espero que las cosas estén claras hasta ahora. Tratamos de ayudar al usuario por defecto algunas cosas para ellos. La forma en que se almacenan las cosas tampoco es genial. El cuadro de diálogo tiene propiedades de lectura/escritura, desde/hasta qué elementos se copian a/desde los controles reales. Luego, en el método principal, hay un "super-almacenamiento" que almacena almacenamientos para cada página. Entonces, cuando el usuario finaliza con la página xy los hits a continuación, primero se copian las cosas de los controles en el almacenamiento que es local para la clase, y luego esas cosas se guardan en el miembro apropiado del super-almacenamiento.
Las matrices (de diálogos/almacenamientos) y los índices no se están utilizando. Existe una lógica "crear & populate" separada pero similar para cada destino goto (etiqueta). Los objetos de diálogo se descartan cuando la página ya no se muestra (no se eliminan, pero cada vez que se muestran, se vuelven a crear y se vuelven a llenar. No creo que sea necesario, ya que solo un Se necesita un único identificador, y después de que se haya mostrado y cerrado, creo que se puede volver a mostrar en el mismo estado, sin tener que volver a llenar los controles. Si desperdiciar la memoria fuera el único problema, probablemente dejaría que las cosas se desmoronaran. pero la cosa no es muy fácil de mantener, por lo que también podría arreglarlo todo para arriba
Pienso:.
- diálogos de almacén en una colección, como por ejemplo una matriz, pero preferiblemente DLL porque sólo puede avanzar 1 o retroceder 1, o solo una de las dos opciones Enumeré (para el primer y último diálogo).
- En realidad, mis pestañas/páginas extienden una clase abstracta común (porque los botones "siguiente", "posterior", "salir" y su comportamiento son comunes a todos).
- Cada pestaña/página/diálogo (lo mismo a los fines de esta pregunta, disculpe la confusión) tendrá propiedades de solo lectura visibles para la clase "conductor".Estas propiedades se derivarán de los valores en los controles (la verdadera fuente de información), a veces las propiedades darán masajes a estos valores un poco. Será responsabilidad del "conductor" tomarlos y guardarlos. Cuando el conductor desea completar el diálogo con un único método (llamémoslo "semilla"). Tengo un poco de dificultad aquí, ya que los parámetros para cada método de semilla serán diferentes. Quiero poder aprovechar la capacidad de tipeo fuerte, así como mantener las cosas genéricas. Sospecho que algo debería dar. Podría pasar un diccionario a cada método de semilla, pero eso se siente demasiado pitónico, como el tipado de patos. No sabría hasta el tiempo de ejecución si lo arruiné. Además, el embalaje y el desempaquetado del diccionario siempre coinciden, para cualquier página determinada. Aquí es donde vendría.
- El almacenamiento global puede ser un diccionario gigante. Puedo ser lo suficientemente disciplinado como para mantener todas las claves diferentes, o prefijo sus nombres con "p1_" a "p5_" dependiendo de una página, solo para estar seguro. Estoy seguro de que existen otros esquemas también. Tener en el diccionario gigante puede ser conveniente al final - allí no importará el orden en que se ensambló la entrada del usuario, siempre que se haga correctamente. También puedo tener una máquina de estado ... más o menos. Aquí es donde también me pierdo en el diseño. Si guardo las cosas en un diccionario, tendría que realizar una gran cantidad de lógica condicional, como: si estoy en la página 2, y hago un cambio, entonces, por lo general (puede haber excepciones), necesito realizar antiguos valores predeterminados si cualquiera para las páginas 3,4,5 no válido. Dependiendo de lo feo que sea, puede que no sea mucho mejor que el diseño actual basado en goto. Sin embargo, creo que puedo hacerlo mejor, ya que puedo implementar mi lógica específica de transición estatal o estatal con un grupo de delegados, manejadores que están almacenados en dos diccionarios (uno para el próximo, uno para el reverso), donde el estado actual es el llave.
Como puede ver, hay algunos desafíos. Tengo la esperanza, sin embargo, porque pensar a través de un buen diseño de mago es una rueda que seguramente fue [re] inventada antes. Quizás puedas recomendar una aplicación C#/mono de fuente abierta que viene con un asistente lineal, pero no trivial, para que pueda echar un vistazo a la implementación. Diablos, tal vez incluso Java/Swing probablemente me convenga, siempre y cuando el mago sea similar en naturaleza. WPF sería otro desafío para mí, no quiero tener 2 problemas en lugar de 1.
Déjame saber lo que se te ocurre. ¿Debería guardar los gotos pero limpiar otras partes tanto como pueda? No dude en hacer preguntas. Gracias,
-HG
Hm ... de esta forma cada "página" debe saber cuáles son todas las demás. Estoy pensando en poder actualizar una "página" después de que se haya construido con cualquier nueva información importante, y hacer que la página devuelva la información importante que se solicitó. Luego, algún tipo de controlador desde el exterior ... –
La página está en la mejor posición para "saber" qué necesita ver el usuario en esa página y para saber qué información necesita para lograrlo. Y la página requiere toda la información que requiere :-). No hay ninguna razón para ocultar fragmentos de información de la página, ya que no hay necesidad de hacer que todo sea demasiado modular. Es decir, a menos que desee reutilizar "módulos" en otro proyecto. En esta solución, aún puede actualizar la página y, de hecho, debe actualizar cada vez que se muestre la página. Pero, si tiene una solución en mente, entonces solo haga eso. – Dialecticus