Inicio > .Net > hawkin > problemas con aplicacion MDI

problemas con aplicacion MDI

Experto:
Usuario:
Fecha: 21/03/2006
Valoración: (5,00 sobre 5) Categoría: .Net
09/03/2006
cespar, usuario preguntando en .Net
Usuario
Hola de nuevo,sinto molestarte otra vez pero me ha surgido un prblemilla que no se por donde atacarlo,a ver si me puedes echar una mano.

Solventado a mi manera el tema de los objetos COM y demas, me ha surgido otro relacionado con aplicaciones MDI.A groso modo mi aplicacion tiene que estar monitorizando el valor de unas variables de un automata,el problema viene cuando abro dos ventanas hijas del formulario MDI,el caso es que los valores que estoy monitorizando solo se ven los cambios cuando la ventana recibe el foco, a mi me gustaria que aunque pierda el foco la ventana siga monitorizando el valor o los valores,no se muy bien como puedo poner eso,he mirao alguna cosilla pero sin acierto,bueno pues nada mas un saludo y gracias!
09/03/2006
cespar, experto respondiendo en .Net
Experto
Tranquilo, no es molestia. Para eso estamos.

Bueno, he hecho una pequeña prueba para comprobar qué te puede estar pasando. El siguente código funciona independientemente de cual es la ventana hija activa:

Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
hijo1 = New Form2
hijo2 = New Form2

hijo1.MdiParent = Me
hijo2.MdiParent = Me

hijo1.Show()
hijo2.Show()
End Sub

Private Sub Timer1_Tick(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Timer1.Tick
hijo1.Label1.Text = Now.ToLongTimeString()
hijo2.Label1.Text = Now.AddHours(3).ToLongTimeString()
End Sub

Entiendo qeu haces algo por el estilo, con lo que debemos buscar algo que podría darte problemas.

La opción más directa que se me ocurre es la resolución de los eventos. Si los cambios en las pantallas vienen dados por eventos, es posible que no te estén llegando a las ventanas que no están activas (me parece raro, pero podría ocurrir), o quizás estos evento llegan pero no se ejecutan por tener que esperar en la cola si tienes alguna funcionalidad que consuma el procesador.

Si es este segundo caso, la solución es fácil. En ese proceso que consume tanto, haz que se pare de vez en cuando para que se ejecuten los eventos en cola. Esto se hace con Application.DoEvents()

Si es el primer caso, la solución podría ser más compleja, y depende de como tengas estructurado el programa.

Se me ocurre también que, dependiendo de cómo lo tengas hecho, hagas como yo, utilizar un temporizador en la ventana padre, y que sea éste el que se encargue de mirar a través del COM los valores que los dispositivos externos.

No sé si te estaré ayudando o te lio más. Si no te resuelve esto, por favor, dame más datos sobre si tienes eventos, temporizadores, etc.

Un saludo.
10/03/2006
cespar, usuario preguntando en .Net
Usuario
Jode macho va a ser que si que controlas un poco del tema.
A ver la manera en que creas los hijos si lo hago de la misma manera que tu,pero como el programa se va haciendo bastante largo pues hago cosas de otra manera que pueden ser la clave del error,te explico:

Bueno referente a llas opciones que has planteado lamento decirte que es mediante eventos,uno en cuestion,es un evento que lo que salta en cuanto hay un cambio en las variables que monitoriza y los puede actualizar cada milisegundo para que te has una idea de los datos que maneja.

La ventana hija basicamente es un treeview donde se explora el autmata y un listview donde se visualizan los datos de las variables,no se si esto ayuda pero te lo digo.

Yo creo que se por donde van los tiros pero las soluciones que se me han ocurrido no me han funcionado te explico:

ahora estoy en casa y no te puedo poner los ejemplos pero por ejemplo controlo el evento MDIChildActivate que es el que me sigue el foco de los formularios por eso de los botones y demas,y a mayores siempre que hago referencia al listview que es donde se tiene que ver el cambio lo hago con

FormMDI.mdichildActive.listview

creo que ahi esta la chicha pero no se como llamar al listview del hijo desde otra clase,tambien he pensado en recorrer todos los formularios hijo darles de alguna manera el foco y que se actualize llamando al evento que me cambia los datos pero no se como hacerlo y no se si esta bien,esto lo mismo te resulta un poco lio mañana te pongo los ejemplos bien puestos pero creo que estoy cometiendo alguna incoherencia por ahi por mi falta de conocimientos,bueno pues lo dicho muchas gracias y mañana a primera hora te pongo los ejemplos a ver is te ayudan algo.

Al final tengo que poner tu nombre en mi proyecto en la parte de agradecimientos,ja ja,bueno,ya me diras
10/03/2006
cespar, usuario preguntando en .Net
Usuario
te mando los ejemplos tal y como los tengo aunque estoy seguro que le problema es como llamo a los hijos en el evento pero no se me ocurre como llamarlos,voy con ello:

Dim hijo As New FormHijo
'dim proy As New ClassLibrary1.Proyecto
hijo.MdiParent = Me

Static nVentana As Integer
hijo.Text = "Proyecto_" & nVentana.ToString
mdi_nombre = hijo.Text
FormMdi.activeChildForm = hijo

hijo.Show()
'Proyecto.NombreProyecto = hijo.Text
Me.activeChildForm.Proyecto = gProyectoActual

asi es como creo los hijos,ahora te mando el evento del cambio de foco


Private Sub FormMdi_MdiChildActivate(ByVal sender As Object, ByVal e As System.EventArgs) Handles MyBase.MdiChildActivate
If Me.ActiveMdiChild Is Nothing Then
Me.Text = "CLIENTE OPC [Sin Documentos]"
Else
Me.Text = "CLIENTE OPC [" & Me.ActiveMdiChild.Text & "]"
'gProyectoActual = Me.activeChildForm.Proyecto
'activeChildForm = Me.ActiveMdiChild


activeChildForm = CType(Me.ActiveMdiChild, FormHijo)
Dim i As Integer
If Not (gCliente.ContadorProyectos) = 0 Then
For i = LBound(gCliente.ListaProyectos) To UBound(gCliente.ListaProyectos)
If gCliente.ListaProyectos(i).NombreProyecto = Me.activeChildForm.Text Then
Me.activeChildForm.Proyecto = gCliente.ListaProyectos(i)
'gProyectoActual = gCliente.ListaProyectos(i)
End If
Next
End If
gProyectoActual = activeChildForm.Proyecto
End If
End Sub

lo que hay de proyectos y eso es xq antes de poner nada aki lo que hacia era si hacia click en una ventana me escribia en la otra siempre de la ventana 0 a la 1 en caso que tuviera 2

Ahora te mando el evento que sobre escribe en el listview en cada cambio,no te lo escribo todo xq es muy largo pero te pnogo lo que yo creo que es crucial

Private Sub gGrupo_DataChange(ByVal TransactionID As Integer, ByVal NumItems As Integer, ByRef ClientHandles As System.Array, ByRef ItemValues As System.Array, ByRef Qualities As System.Array, ByRef TimeStamps As System.Array) Handles gGrupo.DataChange

''Esto de arriba es la declaracion y asi es como llamo al listview del otro de la ventna hija

FormMdi.activeChildForm.ListView1.Items

se que de esta manera lo que hace es solo escribir en la ventana que esta activa xq se lo estoy diciendo yo pero lo que no se es llamar al listview de todas las ventanas y aunque no tengan el foco que siga escribiendo el valor de las variables.


Espero que lo puedas ver claro xq seguno lo estoy escribiendo sale en mil rengolones y no se ve nada,creo que te he puesto lo fundamental para que veas el problema,si necesitas alguna aclaracion mas estoy a tu disposicion y muchas gracias de nuevo

Un saludo!!
13/03/2006
cespar, experto respondiendo en .Net
Experto
Je, creo que al final estamos dando vueltas a algo muy sencillo.

Entiendo que el evento gGrupo_DataChange es del contenedor de mdi, y este se encarga de escribir los datos en los hijos. Si este es el caso, es sencillo de solucionar.

Veo dos posibles casos:
1. Que todas las ventanas tengan que tener los mismos datos. Si este es el caso, en FormMdi.MdiChildren tienes la colección de ventanas hijas. Es una colección de formularios, y con un ForEach tienes solucionado el problema.

2. Que dependiendo de los datos del evento haya que escribir en una ventana hija o en otra. Para esto deberemos utilizar también la colección, pero en la búsqueda ir mirando si la ventana es en la que debes escribir o no.

Para ambos casos, el ListView1 debe ser público en todos los formularios hijos para poder acceder a él, como imagino que estás haciendo.

¿Te soluciona esto el problema?

Un saludo.
13/03/2006
cespar, experto respondiendo en .Net
Experto
Je, creo que al final estamos dando vueltas a algo muy sencillo.

Entiendo que el evento gGrupo_DataChange es del contenedor de mdi, y este se encarga de escribir los datos en los hijos. Si este es el caso, es sencillo de solucionar.

Veo dos posibles casos:
1. Que todas las ventanas tengan que tener los mismos datos. Si este es el caso, en FormMdi.MdiChildren tienes la colección de ventanas hijas. Es una colección de formularios, y con un ForEach tienes solucionado el problema.

2. Que dependiendo de los datos del evento haya que escribir en una ventana hija o en otra. Para esto deberemos utilizar también la colección, pero en la búsqueda ir mirando si la ventana es en la que debes escribir o no.

Para ambos casos, el ListView1 debe ser público en todos los formularios hijos para poder acceder a él, como imagino que estás haciendo.

¿Te soluciona esto el problema?

Un saludo.
13/03/2006
cespar, usuario preguntando en .Net
Usuario
ya creo que se por donde vas pero me sucede una cosa,el evento gGrupo_DataChange no pertence al contenedor de MDI esta implementado en otra clase pero da lo mismo el caso es que cuando lo hago pongo

for i=0 to FormMdi.Mdichildren.length-1
FormMdi.Mdichildren(i).

despues del punto no me deja escoger el Listview1 que tenia como Friend pero ahora tengo coomo publico,pero vamos no solo no me deja acceder a ese sino que tampoco me deja a ningun otro control ni variable,vamos que solo me deja acceder a propiedades de los formularios,no se si hago algo mal.

Respecto a las dos opciones utilizaria la segunda pero si esto que me propones lo lograra funcionar creo que lo echaria a andar.

Parecia mas dificil,vamos si funciona esto

Muchas Gracias,Un Saludo
13/03/2006
cespar, usuario preguntando en .Net
Usuario
de todas formas cuando desde otra clase quiero hacer lo que me indicas cuando pongo

FormMdi.

no me da la opcion de añadirle MdiChildren pero en cambio desde el mismo formulario con me.mdichildren si me deja,a lo mejor tengo que guardar el formulario MDI en una variable global??
13/03/2006
cespar, experto respondiendo en .Net
Experto
Vale, el problema que me planteas ahora se llama polimorfismo. Tu tienes un formulario que herada de Form, y lo que te devuelve MdiChildren son forms. Él, a priori, no sabe que es una clase nueva que hereda de Form.

La forma de solucionar esto es por dos caminos (creo que los dos funcionan, no estoy seguro...):
1. Utilizar ForEach, diciendo que los objetos son FormHijo:

For Each frm As FormHijo In FormMdi.Mdichildren
...
Next

Aqui, en cada pasada, tendrás cada uno de los objetos de la colección, pero como si fueran la clase que tu creaste.

2. Algo parecido a lo que tú has hecho, pero con una asignación importante.

Dim frm As FormHijo

for i=0 to FormMdi.Mdichildren.length-1
FormMdi.Mdichildren(i) <- Esto es un Form
frm = FormMdi.Mdichildren(i) <- Ahora es un FormHijo, lo acabamos de convertir usando polimorfismo.

Espero que ahora sí te funcione.

Un saludo.
13/03/2006
cespar, experto respondiendo en .Net
Experto
Realmente las dos soluciones son la misma, y al final tienes lo que quieres en frm dentro del bucle, pero utilizando dos sentencias diferentes.
14/03/2006
cespar, usuario preguntando en .Net
Usuario
Correcto!!
LLevaba toda la tarde de ayer intentando lo que me has propuesto en tus últimas respuestas y no me iba ni pa dios ya me estaba planteando mandar el MDI a la mierda,pero el caso es que investigando vi que el fallo no era en el propio evento, era en otro sitio que tb lo hacia sobre la ventana activa y tb tenia que recorrer todos los hijos y cuando lo he pillao a funcionado a la perfeccion,muchas gracias me has salvao de una buena.

Hablando de otra cosa,yo lo que quiero es dar la opcion de guardar cada ventana en un fichero como cualquier aplicacion que nos podamos encontrar por ahí y en este caso lo quiero hacer en XML crees que me será muy complicao??la verdad es que no tengo ni idea de XML pero pa eso estamos.

Y una vez acabado esto a meterme con la base de datos que esa es otra,bueno espero que no tengas mas informaciones mias,intentare no molestarme mas pero estoy seguro que en algun momento de desesperacion recurriré a ti,en fin..

Muchas gracias!!
14/03/2006
cespar, experto respondiendo en .Net
Experto
XML es tan sencillo como lo puede ser el un árbol. Tiene su complejidad, pues no debes perder nunca el rumbo dentro del árbol, pero las funciones son muy sencillitas. Están todas dentro de System.Xml.

Un saludo.
21/03/2006
cespar, usuario preguntando en .Net
Usuario
Excelente. Una fantástica solución.
Más opciones
Enlaces patrocinados