Pregunta .net (Objetos)

Sr_RoS

Estoy haciendo un programa en .net y tengo una duda que no se como resolver:

Intentaré explicarme lo mejor posible:

En VB.net tengo varios formularios(form1.vb, form2.vb.....), una clase global(claseGlobal.vb), y varios ficheros xml.

Se supone que la claseGlobal.vb tiene metodos para leer varios ficheros xml(con su schema) y guardar lo leido en un dataTable:

Public Class claseGlobal
Public idUsuario As String
Public dtMarca As Data.DataTable
Public dtModelo As Data.DataTable
'Funcion para leer las marcas del fichero XML
Public Function xmlMarca()
Dim statesDS As New Data.DataSet
Dim aName As String
Dim xmlFileName As String
Dim xsdFileName As String
Try
aName = System.Reflection.Assembly.GetExecutingAssembly.GetModules()(0).FullyQualifiedName
xmlFileName = System.IO.Path.GetDirectoryName(aName) + "/marca.xml"
xsdFileName = System.IO.Path.GetDirectoryName(aName) + "/marca.xsd"
Dim FsXML As New IO.FileStream(xmlFileName, IO.FileMode.Open)
Dim FsXSD As New IO.FileStream(xsdFileName, IO.FileMode.Open)
' leemos el schema del DataSet.
Dim xtrXSD As New Xml.XmlTextReader(FsXSD)
statesDS.ReadXmlSchema(xtrXSD)
xtrXSD.Close()
FsXSD.Close()
' leemos los datos del DataSet.
Dim xtrXML As New Xml.XmlTextReader(FsXML)
statesDS.ReadXml(xtrXML)
xtrXML.Close()
FsXML.Close()
'Guarda la tabla marca en el dt dtMarca.
dtMarca = statesDS.Tables("marca")
Catch exException As Exception 'Exception
Return 0
End Try
Return 1
End Function
End Class

El problema es el siguiente:

Quiero inicializar esta claseGlobal al arrancar el programa y que sea accesible todas las propiedades (dtMarca y dtModelo) desde TODOS los formularios

La pregunta es:

1.- ¿Que tendría que poner el formulario principal para inicializar la claseGlobal?

2.- ¿Que tendría que poner en los sucesivos formularios para poder usar las propiedades de claseGlobal (dtMarca y dtModelo)?

Un saludo y gracias por vuestras respuestas.

IS4kO

¿

Dim instacia as new claseGlobal
Instancia.dtMarca = ....

?

Sr_RoS

tengo puesto esto en el primer form:

Imports applicacionPDA.claseGlobal
Public Class Form1
Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load


    Dim claseGlobal As claseGlobal = New claseGlobal
    If claseGlobal.xmlMarca() = 0 Then
        Label3.Text = "Error al leer los datos locales"
    End If

End Sub

End Class

el problema esque no puedo llamar desde otra función o form a
claseGlobal.dtMarca directamente, me da un error, el visual studio me dice que esta mal hecho

IS4kO

dtMarca que es, una propiedad??, un método??

Sr_RoS

dtMarca es una propiedad que inicializa el metodo "xmlMarca()"

esta bien declarado¿?

IS4kO

No me acuerdo muy bien de la sintaxis de vb, yo diría que lo tienes todo bien, pero cambia la forma en la que instancias por Dim claseGlobal As new claseGlobal

Por lo demás, si xmlMarca devuelve un Integer, si, lo tienes bien declarado.

Que error te da?

Sr_RoS

Dim dv As Data.DataView
dv.Table = claseGlobal.dtMarca<-

Error:
La referencia a un objeto no compartido requiere una referencia de objeto

kas

Le estais diciendo como instanciar un objeto y el os esta preguntando como hacerlo visible desde todos los formularios, si mal no he entendido.

TuProyecto, boton derecho, agregar / modulo.

'
' Clase
'
Public Class ClaseGlobal
.... ' tus funciones ..
End Class
'
' Modulo
'
Public Module PonAquiTodoLoVisibleParaTodoElProyecto

.... Public ClaseGlobal m_ClaseGlobal;

End Module

'
' Instancia en tu Form
'
Public Class Form1 inherits Form

.... Public Sub Form1_Load(....)

........ m_ClaseGlobal = new ClaseGlobal()
.... End Sub
End Class

Sr_RoS

y si quisiera usarlo en otro form?
seria esto?

Public Class Form2 inherits Form

.... Public Sub Form2_Load(....)

........ loQueSea = m_ClaseGlobal."propiedad"
.... End Sub
End Class

sería ese el uso?

kas

EDITO:Si, efestiviwonder seria tal como posteas el uso, por si acaso, dejo la explicacion "teorica abajo".

<strike>Ehm... no.</strike>

Solo deves instanciarlo 1 vez. Tipicamente en la inicializacion del programa, que acostumbra a ser el Form principal (el primero qeu se ejecuta).

Una vez instanciado, solo tienes que llamar al objeto como si lo hubieras declarado en el form en le que estes:

'
' Primer formulario que se ejecuta del programa
'
Public Class Form1

.... public sub Form1_Load(...)
.... .... m_ClaseGlobal = New ClaseGlobal(...)
.... end sub

End Class

'
' Cualquier otro formulario
'
Public Class FormX

.... ' Por ejemplo usando la clase al clickar un boton
.... public sub Button1_click(...)
.... .... m_ClaseGlobal.TusFunciones(..)
.... end sub
End Class

kas

Te puedo dar un consejo:

Si tienes una clase, cuyas funciones no necesitan de ninguna variable interna, puedes decalarar tanto la clase como las funciones como estaticas (Shared en VB.NET, static en C#).

Una clase estatica no se puede instanciar y sin embargo puedes usar sus funciones. Ejemplo:

public shared class ClaseEstatica
.... public shared function Suma(int a, int b) as integer
.... .... return a + b
.... end function
end class

public class Form1 inherits Form
.... private sub button1_click(...)
.... .... MsgBox( ClaseEstatica.Suma(txt1.text, txt2.text) )
.... end sub
end class.

Así, siendo la clase publica, no necesitas tener la instancia almacenada en ningun lado, ya que si es publica es visible por todo el mundo y siendo shared no necesitas la instáncia para acceder a las funciones.

Realmente, tambien puedes tener variables (que deben ser estaticas tambien) en esa clase, con sus propiedades publicas.

Mas info:

Diseño de clases estaticas: http://msdn2.microsoft.com/en-us/library/ms229038(VS.80).aspx
Instancia vs Estatico
http://visualbasic.about.com/od/learnvbnet/a/sharedinstance.htm

Yo estoy utilizando bastantes clases estaticas en un proyecto que posteare a finales de enero, por ser "agrupaciones de funciones" mas que un objeto propiamente dicho.

Mucha suerte.

kas

Otra cosa que debes tener en cuenta cuando manejes clases estaticas:

Como has visto, no se pueden instanciar, por lo que la pregunta que surje es:

Si no se intància, cuando reserva el sistema la memoria necesaria para almacenar esta clase con sus funciones?

Facil: Una clase estatica tiene el mismo tiempo de vida que el software que la usa.

Esto quiere decir que cuando arrancas el programa, las clases estaticas se cargan en memoria y no son destruidas hasta que el software termina.

Si es adecuado o no el uso "extra" de memoria cuando esta clase no se usa, debes decidirlo tu. Si es una MEGA-CLASE con muchisisimas funciones, quizas debas plantearte 2 cosas:

1) Separar en clases estaticas mas pequeñas segun "ambitos de uso"

2) No utilizar clases estaticas e instanciar cuando sea necesario.

Solo queria matizar esto, que no se ve a simple vista, pero que es bastante importante, ya que es uan de las caracteristicas principales de las clases estaticas.

Sr_RoS

el objetivo es terner varios dataTables en memoria ya que es necesario accdeder a todos ellos ya que se necesitan para la funcion principal del programa, rellenar unos combobox dinamicamente, y que el usuario pulse lo menos posible la pantalla (es para compact framework)

un saludo y mil gracias

kas

Siempre puedes tener en cada form una viarable de tipo DataTable, con su propiedad publica:

'
' En Form2
'
Dim _datos As DataTable
Public Property Datos As DataTable

.... Get
.... .... return _datos
.... End Get
.... Set ( value As DataTable)
.... .... _datos = value
.... End Set

End Property

'
' En Form1, que tiene el DataTable original
' creando un Form2 y pasando el DataTable
'
Dim m_datos As DataTable
private sub LaFuncionQueSea()
.... Dim frm2 As New Form2()
.... frm2.Datos = m_datos
.... frm2.Show()
end sub

Así lo que usas es una sola variable que tu decides quien la tiene.

La tecnica del modulo, aunque valida, es mas bien un pegote.

14 días después
Sr_RoS

Probado y 100% funcional
Gracias

Usuarios habituales

  • Sr_RoS
  • kas
  • IS4kO