Introducción
Existen varias formas pasar información entre formularios, especialmente si queremos hacerlo sin generar una fuerte dependencia entre estos.
Este mismo tema lo había abordado en artículos anteriores por lo que retomaremos el análisis de las distintas formas de lograr la comunicación sin generar dependencia entre los forms
Los artículos anteriores en los cuales he tratado el tema:
Comunicar formularios de forma desacoplada
Para ejemplificar haremos uso de un form que permite listar y editar productos de la base de datos Northwind.
Analizaremos 3 formas de comunicar formularios y enviar datos entre ellos:
- Usando Interfaces
- Usando eventos
- Usando el evento FormClosed
Usando interfaces
Una interfaz permite definir un contrato entre clases, permitiendo que una invoque la funcionalidad de cualquier otra que respete ese contrato definido.
Recordemos que los formularios en definitiva no son mas que clases que se instancian por lo que puede aplicarse los mismos conceptos de POO (Programación orientada a objetos).
La implementación de esta técnica se encuentra en la búsqueda de un proveedor en el form de edición de los productos.
El primer paso será definir la interfaz
siendo implementada por el formulario padre receptora de la información seleccionada por el usuario
El form padre será quien instancie el form hijo pasando su instancia por parámetro en el constructor, además de algún otro valor adicional de ser necesario, como en este caso un filtro para limitar los ítems visualizados en el grid de selección.
Desde el form hijo (frmFindSupplier) se define el constructor que recibirá los parámetro
La variable “caller” contendrá la instancia del form padre que implementa la interfaz, mientras que “_supplierName” tendrá el input del usuario para filtrar las entidades.
Al seleccionar un ítem del grid se dará por seleccionada la entidad y se enviara la acción al form padre a través de la instancia invocando el método definido en la interfaz.
Primero se valida que exista selección en el grid, se recupera la entidad seleccionada pasándola como parametro al método Selected() definido en la interfaz, por ultimo se cierra el formulario. El form padre recibe el valor seleccionado y actualiza los controles o entidades que hagan falta.
La secuencia completa quedaría de esta forma
- El form padre (frmEditProductos) implementa la interfaz.
- En el botón de búsqueda se crea la instancia del form hijo (frmFindSupplier), pasando como parámetro en el constructor la instancia del forma padre (utilizando this)
- El form hijo recibe en el constructor los valores por parámetro
- Se selecciona un ítem del grid y se invoca al método de la interfaz
- El form padre recibe la selección y actualiza los datos
Como ventaja se puede mencionar que cualquier form que implemente la interfaz podrá reutilizar la funcionalidad de búsqueda implementada al no quedar acoplados los formularios que interactuan.
Usando eventos
Permite enviar una acción directa al form que se subscriba al evento.
El ejemplo va a estar representado en la comunicación del form de edición de productos y la búsqueda de categorías.
Partamos analizando la implementación del form hijo (frmFindCategory), este expone el evento, que es lanzado cuando se selecciona una categoría del grid
Para definir datos específicos en el intercambio de información se crea una clase que hereda de EventArgs
Desde el form padre (frmEditProductos) simplemente se debe adjuntar al evento la instancia del form hijo
Repasemos como seria la ejecución en secuencia
- El form hijo expone el evento, utilizado para informar la selección a quien lo haya invocado.
- Se define una clase que hereda de EventArgs para poder pasar información adicional como argumento del evento.
- El form padre que realiza la búsqueda crea la instancia del forma hijo y se adjunta al evento, además crea el método que recibirá la acción.
- Cuando se selecciona un ítem del grid se valida si alguien esta adjunto en el evento y se invoca.
Actualizar los datos al cerrar el form (evento FormClosed)
Para actualizar un grid luego de una acción en otro form podría utilizarse eventos existentes, como ser el FormClosed, con este evento se puede realizar una acción al cerrar un form
Analicemos los pasos
- En el form padre (frmAdminProducts) instancia el form hijo (frmEditProductos) y se adjunta el evento de cierre del form
- Cuando se presiona el boton de aceptar o cancelar se devuelve el DialogResult cerrando el form, esto lanza el evento FormClosed
- Desde el form padre se atrapa el evento y se realiza la recarga de los datos del grid
Descarga
El articulo fue desarrollando usando Visual Studio 2012, la base de datos es Sql Compact (.sdf)
Durante la compilación se descargaran las dependencias por medio de Nuget.
[C#] |
Hola que tal, no comprendo muy bien el uso con eventos, podria subir un ejemplo más sencillo modificando un textbox desde otro,,,Gracias!!!
ResponderEliminarhola Juan
ResponderEliminarpero que seria exactamente lo que no quedo claro, porque en el ejemplo si bien no es un textbox estoy actualizando un label y la propiedad de la entidad que se edita
digo, no es un textbox pero un label se le parece mucho
saludos
Ok, disculpa, voy a hacer más pruebas y veré porque no me sale,y ya entonces te notificaré de los problemas que tuve gracias, y tienes mucha razón con lo del label,,, gracias...
ResponderEliminarHola que tal de nuevo, pues ahora lo intente con delegate y me funciono también, gracias por la ayuda porque tu ejemplo me ayudo a investigar más, a lo mejor no sabía por donde empezar y con tu artículo pude solucionar mi problema gracias.!!!!!!!
ResponderEliminarHola que tal de nuevo, pues ahora lo intente con delegate y me funciono también, gracias por la ayuda porque tu ejemplo me ayudo a investigar más, a lo mejor no sabía por donde empezar y con tu artículo pude solucionar mi problema gracias.!!!!!!!
ResponderEliminarhola Leo ! podras hacer alguna entrada acerca de clickonce!
ResponderEliminarGracias por tus aportes y saludos
hola Patos
ResponderEliminarpero hay hay buena info sobre clickonce
[Second Nug] ClickOnce, tus aplicaciones llegarán a cualquier parte
saludos
Hola Leandro Estoy en un proble nose si puedas ayudarme enviandome un tutotial o manual para hacer un reporte con subreport(rdlc) estoy buscando han la web y no encuentro nada. por favor ayudame
ResponderEliminarha leandro estou usando sql server 2008 y visual studio 2010 aplicacion escritorio aydam con un toturial de Reportes y subreporte
ResponderEliminarhola Deyvi
ResponderEliminarbuscas algo como esto
Building Subreport in Reporting Services
si bien alli conecta el reporte directo a los datos podria trabajarse de la misma forma si usas un reporte local conectado a un dataset tipado o coleccion
saludos
Hola Leandro.
ResponderEliminarmi sonsulta no tiene nada que ver con el tema. Quisiera que me ayudes con una duda, tengo un form .NET 2012. deseo que los usuarios envien correos electrónicos a Help Desk desde cualquier cuenta de correo ya sea hotmail, gmail e incluso los correos creados con un dominio privado de cualquier empresa.
es posible hacer eso?,tienes un ejemplo?
hola Marcos
ResponderEliminarsi cuentas con un servicio de SMTP con el cual conectarte para enviar los mail claro que podrias
aqui
MailMessage - Envia mail con GMail (1/3)
envio mail usando el smtp de gmail, pero si tienes el de hotmail o algun otro tambien es valido
el tema es que necesitaras de una cuenta con la cual autenticarte, ya que no permiten enviar mail anonimos
saludos
Hola Leandro, como estas, oye en el ejemplo de las interfaces veo que hay una clase(creo) que se llama Supplier... void Selected(Supplier supplier);... mi pregunta es como defines esa clase o que es... se que tiene que ver con proveedores pero no entiendo... Gracias
ResponderEliminarhola JCLamer
ResponderEliminarveras que hay un archivo IFindSupplier
alli se define la interfaz que el form debe implementar para poder comunicarse con el otro form
la entidad que se uso en este caso es la de Supplier (proveedor), pero puedes usar la que tu necesites, o un valor simple como un string, int, etc
mientras lo definas en la interfaz
saludos
Primero que todo agradecer por esos aportes tan valiosos que nos brindas a todos, en ocasiones me atraso mucho en el desarrollo talvez de algo "sencillo" pero me gusta que sea de calidad y por eso siempre consulto tu blog.
ResponderEliminarMi pregunta. Defines este codigo public frmEditProductos(int productId)
: this()
{
Product prod = ProductRepository.GetById(productId);
_product = prod;
}
pero en que escenario o parte del codigo se utiliza porque no le encuentro donde..
hola Eyder
ResponderEliminaralli lo que haces es recuperar la entidad producto en base al id que llega en el constructor del formulario de edicion
como veras el producto se asigna a la variable definida a nivel del formulario, con esto en el Form_load podrias poner los valores de las propiedades en los controles
basicamente en el constructor recuperas la entidad de la db y en el load del form asignas los controles para mostrar los datos
saludos
Muy buen articulo me sirvio mucho. Hay algo que no entiendo como lo hiciste es cuando casteas o convertis explicitamente el DATABOUNDITEM como tipo Supplier, como lograste sobrecargar el operador explicito. No puedo ver el codigo ya que tengo una version de Visual mas antigua que la version con la que subiste las soluciones
ResponderEliminarhola German
ResponderEliminarel DataBoundItem es una propiedad del row del grid que devuelve la instancia que se bindeo a esa row cuando se generaron las rows, no hay ninguna sobrecarga porque no hay ningun metodo
si asignas al DataSource del grid una List entonces el item puede castearlo a ese tipo
si asignas un datatable entonce el DataBoundItem podrias castearlo al DataRowView
saludos
Gracias, ya comprendi.
ResponderEliminarAhora una pregunta algo mas tonta, que propiedades aplicas para el titulo de las ventanas que es marron y las letras en blanco? se ve bueno
hola German
ResponderEliminaren realidad es un banner gris
alli uso un label al cual le defino la propiedad AutoSize = true
y la propiedad Dock = Top
despues es solo cambiar el color del fondo y la fuente
saludos
Excelente Explicación !
ResponderEliminarPor casualidad no tienes el ejemplo en vb .net, por otro lado estoy dando los primeros pasos para cambiarme a c# algun material que me puedas sugerir para hacerlo de la forma correcta.
ResponderEliminarHola Leandro, muy buenos todos tu ejemplos!, la verdad que aprendí mucho con tu blog, Seguí así. Muchas Gracias!
ResponderEliminarBuenas. metodo me aconsejas para pasar una instancia de una clase de un form padre a hijo y viceversa ?? gracias por la ayuda. Saludos
ResponderEliminarhola
Eliminarpuedes aplicar la misma tecnica descripta en el articulo, que sea un valor simple o una instancia de clase no varia
puedes pasar en el constructor o en algun metodo que exponga el form hijo la intancia de la clase
y desde el form hijo al padre teniendo la instancia de este ultimo puedes invocar un metodo pasandole por parametro la instancia, aunque recuerda que esta se pasa por referencia por lo que si la creas desde el padre al pasarla al hijo y este modificarla tambien altera los valores en el padre
saludos
excelente trabajo este blog me ha sido de gran ayuda, saludos!
ResponderEliminarHola, que tal, como se haría en WPF, los metodos no son los mismos. y no logro hacer el primer o segundo ejemplo.
ResponderEliminarGracias, yo no hacia exactamente eso pero me sirvió para lo que lo ocupaba ya que metro controles de usuario dentro de paneles dentro de un form principal y ver tu ejemplo me abrió los ojos y ya puedo abrir otros controles al panel principal desde controles hijos
ResponderEliminarY que te parece usar propiedades para pasar parametros?
ResponderEliminarleandro ayer te envie una invitacion de chat en el hangouts de gmail.
ResponderEliminarPodrias aceptarme? Es para consultarte unas dudas que tengo de un proyecto del trabajo.
Gracias.
Espero noticias tuyas lo mas pronto posible
Este comentario ha sido eliminado por el autor.
ResponderEliminarbuenas tardes, me gustaría saber si usas alguna directiva using especifica para lo que estas explicando, ya que cuando quiero generar la interfaz IFindSupplier no me lo acepta.
ResponderEliminarHola Leandro, la use en Windows Forms en su momento y ahora necesitaba algo simple para WPF y me acorde de esto, otra vez, gracias!!
ResponderEliminarBuenas, estoy iniciando en asp.net mvc y tengo que realizar algo parecido a este proceso. Es para mi tesis, cuando voy a cargar un alumno tengo una caja de texto para buscar la localidad y en caso de que no este agregada, tengo que ir a la vista de localidades, agregarla y automáticamente volver a la vista donde estoy creando al alumno y que en la caja de texto me aparezca dicha localidad y por supuesto tiene que quedar grabada en la tabla localidades. Agredeceria de su ayuda
ResponderEliminarWow! this is Amazing! Do you know your hidden name meaning ? Click here to find your hidden name meaning
ResponderEliminarBuenas tardes, yo abro formularios hijo en un panel contenedor del formulario padre de esta forma:
ResponderEliminarprivate void AbrirFormulario(Form FormularioHijo)
{
FormularioActual = FormularioHijo;
FormularioHijo.TopLevel = false;
FormularioHijo.FormBorderStyle = FormBorderStyle.None;
FormularioHijo.Dock = DockStyle.Fill;
PanelContenedor.Controls.Add(FormularioHijo);
PanelContenedor.Tag = FormularioHijo;
FormularioHijo.BringToFront();
FormularioHijo.Show();
}
Ahora bien, deseo que desde el formulario hijo poder afectar algun control en el formulario padre, por ejemplo; el botón que use para llamarlo cambio de color para indicar que esta abierto, quiero que al cerrarlo, se llame a regresar al color original, y así mismo, cambiar el nombre del titulo del formulario activo, es un label en el formulario padre principal. He intentado estos procedimientos pero aunque no me marca ningun error, no se realizan los cambios... como si simplemente los ignorara.
Vi este video y me funcionó y me permitió descargar el proyecto , se los comparto! https://www.youtube.com/watch?v=OZ2fEo5EBUE&t=2s
ResponderEliminarGracias maestro Leandro Tuttini
ResponderEliminar¿Estás pasando por una ruptura dolorosa o un divorcio? Gánate a tu exnovio, exnovia, exmarido, exesposa y mantenlos permanentemente. Mi esposo me dejo por otra mujer hace 6 meses y desde entonces mi vida ha estado llena de dolor, tristeza y desamor pues fue mi primer amor con quien he pasado toda mi vida. Un amigo me dijo que vio algunos testimonios de un lanzador de hechizos llamado DR SUNNY que puede traer a su amante de regreso en unos días, me río y dije que no estoy interesado, pero debido al amor que mi amigo me tenía, ella . Consulté al sumo sacerdote en mi nombre y, para mi mayor sorpresa, después de 2 días, mi esposo me llamó por primera vez después de 6 meses que me extrañaba y que lamentaba todo lo que me hizo pasar. para mí y ahora somos felices juntos. Todavía no puedo creerlo, porque es tan increíble. Gracias DR SUNNY por traer de vuelta a mi amante y también a mi adorable amiga que intercedió por mí, para cualquier persona que pueda necesitar la ayuda de este gran Dr. aquí está el correo electrónico: drsunnydsolution1@gmail.com También puede enviarlo por WhatsApp a +2348082943805
ResponderEliminar