Pregunta básica

21/12/2005 - 23:28 por Novato | Informe spam
Hola, perdonad por la pregunta pero es que nunca encuentro cómo puedo hacer
algo.

Si tengo un formulario, que lanza otro (.showdialog) y necesito que cuando
se cierre el formulario lanzado, recoger una serie de valores del mismo
formulario... ¿cómo puedo hacer eso?

- ¿Con propiedades en el formulario lanzado y controlando desde el
formulario lanzador el evento closing del otro formulario?
- ¿Hay alguna otra forma de hacerlo?

Muchas gracias

Preguntas similare

Leer las respuestas

#6 Mario Vázquez
23/12/2005 - 09:18 | Informe spam
Supongamos que un Form1 debe abrir un Form2 y que cuando éste se cierre,
Form1 debe de poder acceder a algún valor obtenido desde Form2.
En Form1 tendríamos un código como:

Public Sub Test()

Dim frm As Form2
Dim Valor As Decimal

frm = new Form2
if frm.ShowDialog() = DialogResult.OK Then
Valor = frm.Valor
End if
End Sub

Este ejemplo abre el 2º formulario modalmente, lo cual facilita las cosas.
Supongamos que en Form2 tenemos que obtener un valor de un TextBox, que es
el que necesita Form1.
Una posibilidad es hacer ese TextBox público para ser accedido desde Form1.
De entrada, en Form2 tenemos un TextBox, mientras que en Form1 necesitamos
un Decimal. VB nos permite cosas tan feas como hacre esto desde Form1: Valor
= frm.TextBox1.Text
Esto no es nada recomendable. A parte de vulnerar el principio de
encapsulación, podemos encontrarnos con muchas sorpresas. Por ejemplo, ¿qué
pasa si frm.TextBox1.Text = ""? ¿o si frm.TextBox1.Text = "A"?. A parte la
gestión de TextBox1 debería ser un asunto privado de Form2, desde dónde
deberíamos asegurarnos de que nadie pudiera manipular ese objeto
erroneamente.

Yo haría lo siguiente en Form2:

Private TextBox1 As TextBox ' El diseñador de VB declara los objetos
Friend.


Public ReadOnly Property Valor As Decimal
Get
if Me.TextBox1.Text.Trim() = "" OrElse Not IsNumeric(
Me.TextBox1.Text ) Then
Return 0
Else
Return CDec( Me.TextBox1.Text )
End Get
End Property

La misión de la propiedad es "publicar" de forma segura el valor que
necesitamos externamente. Por un lado evitamos que nadie puede manipular el
TextBox de Form2, y por otro devolvemos el tipo esperado (Decimal) de forma
segura y elegante.
Si un día Form2 se complica y el valor que debemos devolver se obtiene de un
ListBox, sólo deberemos tocar el código de la propiedad. Form1 seguirá
recibiendo su valor Decimal


Si desde Form1 necesitáramos establecer el valor de TextBox1, deberíamos
ampliar la propiedad de Form2:

Public Property Valor As Decimal ' Ahora sin ReadOnly
Get
if Me.TextBox1.Text.Trim() = "" OrElse Not IsNumeric(
Me.TextBox1.Text ) Then
Return 0
Else
Return CDec( Me.TextBox1.Text )
End Get
Set( value As Decimal )
Me.TextBox1.Text = CStr( value )
End Set
End Property

En este caso el bloque Set nos sirve también para convertir adecuadamente el
valor de entrada (Decimal) al control que lo va a gestionar (TextBox,
ListBox o lo que sea).

He explicado un ejemplo abriendo Form2 como formulario modal. Si lo abrimos
con Show(), puede que necesitemos un mecanismo para saber desde Form1 cuándo
la propiedad de Form2 ha cambiado. Una forma para conseguir esto sería
creando un evento en Form2 que pueda ser recogido por Form1:

' En las declaraciones
Public Event ValorCambiado( sender As object, valorAntiguo As Decimal,
valorNuevo As Decimal )

' En el boque set de la propiedad Valor
'...
Set( value As Decimal )
RaiseEvent ValorCambiado( Me, Me.Valor, value )
Me.TextBox1.Text = CStr( value )
End Set

Espero que te ayude en algo.
Saludos,
Mario Vázquez



"Cid" escribió en el mensaje
news:
Mario me ayudaria si me puedes enviar un ejemplo, gracias.




"Mario Vázquez" escribió en el mensaje
news:
Puedes acceder a los miembros de un formulario aun después de que éste se
haya cerrado, por lo que no creo que sean necesarias muchas maniobras.

Yo hago lo siguiente:

En el formulario que tiene que devolver valores, escribo propiedades
(property) de sólo lectura para devolver estos valores en el tipo
correcto (me refiero que si tienes que devolver un entero obtenido desde
la propiedad Text de un TexBox, declaro la propiedad como entero, y en el
código de ésta hago la conversión y validación correspondientes).
Desde el formulario llamador, simplemente accedo a las propiedades
ReadOnly del formyulario llamado.

Saludos,
Mario Vázquez


"Novato" escribió en el mensaje
news:%
Hola, perdonad por la pregunta pero es que nunca encuentro cómo puedo
hacer algo.

Si tengo un formulario, que lanza otro (.showdialog) y necesito que
cuando se cierre el formulario lanzado, recoger una serie de valores del
mismo formulario... ¿cómo puedo hacer eso?

- ¿Con propiedades en el formulario lanzado y controlando desde el
formulario lanzador el evento closing del otro formulario?
- ¿Hay alguna otra forma de hacerlo?

Muchas gracias










Respuesta Responder a este mensaje
#7 Cid
23/12/2005 - 12:31 | Informe spam
Y si tambien se necesita pasar parametros al reves? En 2003 yo sabia hacerlo
trabajando sobre el constructor pero en 2005 no me sale...


"Leonardo Azpurua [mvp vb]" <l e o n a r d o (arroba) m v p s (punto) o r g>
escribió en el mensaje news:%

"gilberto.najera" escribió en el mensaje
news:%
La mejor opción, a mi forma de ver, es utilizar propiedades (variables
públicas) en el lanzador y pasarle los valores desde el lanzado, ya sea
con lanzador.ActiveForm

en lanzado.deactivate
lanzador.ActiveForm.propiedad=prop

o bien con una copia de lanzador en lanzado:

En lanzador:
lanzado.lanz=me
lanzado.show

En lanzado.deactivate:
lanz.propiedad=prop

Espero te sea útil.



Hola, Gilberto:

Los axiomas básicos de la OO indican que el objeto llamado (servidor) no
debe asumir nada con respecto a lo que sabe o no sabe quien lo llama (su
cliente). Claro que lo que tu sugieres es un protocolo establecido, es
decir:

"Para llamar a una forma X, debo declarar tales propiedades publicas con
acceso de escritura, y debo pasarle a X una referencia a Me".

No esta mal, pero es complicado.

Una forma más elegante es implementar en la misma forma X una función que
abre la forma (lo mas facil es mediante ShowDialog, lo mas sucio, pero
tambien funciona, es abrirla de manera no modal -i.e. solo Show- y luego
iterar llamando a Application.DoEvents mientras este visible) y al
cerrarse toma los valores a devolver y los coloca en una estructura que es
el valor de retorno de la función. Antes de salir, llama a Dispose (para
dejar todo limpio).

Por ejemplo:

Public Structure ParametrosRetorno
Codigo As String
Descripcion As String
Precio As Decimal
End Structure

Public Function GetValores() As ParametrosRetorno
Dim retP as ParametrosRetorno
If Me.ShowDialog = DialogResult.OK Then
retP.Codigo = txCodigo.Text
retP.Descripcion = txDescripcion.Text
retP.Precio = numPrecio.Value
Else
retP.Codigo = "NULL"
End If
Dispose
Return retP
End If

Desde el cliente, lo unico que tienes que hacer es:

Dim xForm As New FormaX
Dim resultado As FormaX.ParametrosRetorno = FormaX.GetValores()
If resultado.Codigo <> "NULL" Then
...
End If

Lo que me gusta de este metodo es que las formas se convierten, desde el
punto de vista del diseño, en objetos como todos los demas: el hecho de
que interactúen con el usuario es sólo una incidencia que no nos interesa
en el punto donde estamos.

Salud!


Respuesta Responder a este mensaje
#8 Leonardo Azpurua [mvp vb]
26/12/2005 - 15:32 | Informe spam
"Cid" escribió en el mensaje
news:
Y si tambien se necesita pasar parametros al reves? En 2003 yo sabia
hacerlo trabajando sobre el constructor pero en 2005 no me sale...



Hola.

Los constructores parametrizados funcionan en VB2005 igual que en las
versiones anteriores.

La unica diferencia es que en VB2005 puedes utilizar la "instancia por
default" de los formularios (es decir, puedes escribir directamente
"Form1.ShowDialog()", que sigue siendo tan poco recomendable como lo era con
VB5). Lo único que debes tener presente es agregar una llamada a
"InitializeComponent()" en los cosntructores que tu mismo agregues.

Aunque siempre tienes la opción de pasar los argumentos en la llamada a la
función.

Salud!
Respuesta Responder a este mensaje
#9 Cid
26/12/2005 - 19:40 | Informe spam
Ok gracias

"Leonardo Azpurua [mvp vb]" <l e o n a r d o (arroba) m v p s (punto) o r g>
escribió en el mensaje news:

"Cid" escribió en el mensaje
news:
Y si tambien se necesita pasar parametros al reves? En 2003 yo sabia
hacerlo trabajando sobre el constructor pero en 2005 no me sale...



Hola.

Los constructores parametrizados funcionan en VB2005 igual que en las
versiones anteriores.

La unica diferencia es que en VB2005 puedes utilizar la "instancia por
default" de los formularios (es decir, puedes escribir directamente
"Form1.ShowDialog()", que sigue siendo tan poco recomendable como lo era
con VB5). Lo único que debes tener presente es agregar una llamada a
"InitializeComponent()" en los cosntructores que tu mismo agregues.

Aunque siempre tienes la opción de pasar los argumentos en la llamada a la
función.

Salud!


Respuesta Responder a este mensaje
#10 Cid
26/12/2005 - 19:40 | Informe spam
Ok gracias

"Leonardo Azpurua [mvp vb]" <l e o n a r d o (arroba) m v p s (punto) o r g>
escribió en el mensaje news:

"Cid" escribió en el mensaje
news:
Y si tambien se necesita pasar parametros al reves? En 2003 yo sabia
hacerlo trabajando sobre el constructor pero en 2005 no me sale...



Hola.

Los constructores parametrizados funcionan en VB2005 igual que en las
versiones anteriores.

La unica diferencia es que en VB2005 puedes utilizar la "instancia por
default" de los formularios (es decir, puedes escribir directamente
"Form1.ShowDialog()", que sigue siendo tan poco recomendable como lo era
con VB5). Lo único que debes tener presente es agregar una llamada a
"InitializeComponent()" en los cosntructores que tu mismo agregues.

Aunque siempre tienes la opción de pasar los argumentos en la llamada a la
función.

Salud!


email Siga el debate Respuesta Responder a este mensaje
Ads by Google
Help Hacer una pregunta AnteriorRespuesta Tengo una respuesta
Search Busqueda sugerida