Abrir form usando una variable de cadena de caraceteres.(SOLUCIONADO)

Iniciado por ezugaru, 14 Junio 2010, 18:53 PM

0 Miembros y 3 Visitantes están viendo este tema.

ezugaru

 :-(
Que tal amigos? fijense que ando desarrollando una aplicacion con menús dinámicos en VB.Net , los menús me corren de maravilla, sin embargo mi problema viene en la conversion de el nombre del frm que se obtiene de la base de datos en tipo cadena a un objeto de tipo form que pueda usarse para invocar el formulario correcto.

Encontré varios códigos en internet, pero ninguno me ha funcionado, el que actualmente estoy trabajando es este:


Imports MySql.Data
Imports MySql.Data.MySqlClient
Imports System
Imports System.Reflection
Imports Microsoft.VisualBasic.CallType


Public Class Main

   Public user, idrol, iuseraccessmode As String

   Dim consulta As String
   Dim con As New MySqlConnection
   Dim comando As New MySqlCommand
   Dim adaptador As New MySqlDataAdapter
   Dim lector As MySqlDataReader
   Dim datos As New DataTable
   Dim mnMenu As MenuStrip

   Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load

       LoginForm1.Close()
       'MsgBox(iuseraccessmode)

       con = New MySqlConnection
       con.ConnectionString = "server = 192.168.1.3;" & "user = zzzzzzzz;" & "password = xxxxxxxxx;" & "database = xxxxxx;"

       Try

           con.Open()

           consulta = "Select menutext from menumaster Where mainmenu = 0" & _
                  " And menuid in (Select menuid from acceso Where idrol =" & _
                   CInt(iuseraccessmode) & ") " & _
                   "And isActive = 1"
           comando.Connection = con
           comando.CommandText = consulta
           lector = comando.ExecuteReader

           If lector.HasRows Then

               mnMenu = New MenuStrip

               While lector.Read()

                   mnMenu.Items.Add(lector(0).ToString, Nothing, New System.EventHandler(AddressOf MainMenu_OnClick))
                   Me.Controls.Add(mnMenu)

               End While
           End If

           lector.Close()

       Catch ex As Exception

           MsgBox("El siguiente error fue detectado: " & ex.Message.ToString, MsgBoxStyle.Critical)

       End Try

       con.Close()

   End Sub

   Private Sub MainMenu_OnClick(ByVal sender As Object, ByVal e As System.EventArgs)
       Dim cms As New ContextMenuStrip()
       Dim sMenu() As String
       con = New MySqlConnection
       con.ConnectionString = "server = 192.168.1.3;" & "user = xxxxxxxx;" & "password = xxxxxxxx;" & "database = xxxxxxxx;"

       Try

           con.Open()

           consulta = "Select menuid from menumaster Where menutext = '" & sender.ToString & "'"
           comando.Connection = con
           comando.CommandText = consulta
           lector = comando.ExecuteReader

           Dim parentMenuID As Integer

           If lector.HasRows Then
               lector.Read()
               parentMenuID = lector("menuid")
           End If
           lector.Close()

           consulta = "Select menutext from menumaster Where mainmenu ='" & _
            parentMenuID & " '" & _
            "And isActive = 1" & _
            " And MenuID in (" & _
            "Select menuid from acceso Where idrol =" & _
            CInt(iuseraccessmode) & ")" & _
            " Order BY MenuOrder"
           comando.Connection = con
           comando.CommandText = consulta
           lector = comando.ExecuteReader

           ReDim Preserve sMenu(0)
           Dim i As Integer
           If lector.HasRows Then
               ReDim Preserve sMenu(0)
               i = 0
               While lector.Read()
                   ReDim Preserve sMenu(i)
                   sMenu(i) = lector("menutext")
                   i = i + 1
               End While
           End If
           lector.Close()
           For Each sMn As String In sMenu
               cms.Items.Add(sMn, Nothing, New System.EventHandler(AddressOf SelectedChildMenu_OnClick))
           Next
           Dim tsi As ToolStripMenuItem = CType(sender, ToolStripMenuItem)
           tsi.DropDown = cms
           tsi.ShowDropDown()

       Catch ex As Exception

           MsgBox("El siguiente error fue detectado: " & ex.Message.ToString, MsgBoxStyle.Critical)

       End Try

       con.Close()

   End Sub

   Private Sub SelectedChildMenu_OnClick(ByVal sender As Object, ByVal e As System.EventArgs)
       
       Dim frmName As String
       'Dim frm As New Form

       con = New MySqlConnection
       con.ConnectionString = "server = 192.168.1.3;" & "user = xxxxxxxxx;" & "password = xxxxxxxxx;" & "database = xxxxxxx;"

       Try

           con.Open()
           consulta = "Select formname from menumaster Where menutext = '" & _
           sender.ToString & "'"
           comando.Connection = con
           comando.CommandText = consulta
           lector = comando.ExecuteReader

           If lector.HasRows Then

               lector.Read()
               frmName = lector(0).ToString
               lector.Close()

               Dim frm As Form = DynamicallyLoadedObject(frmName)
               frm.MdiParent = Me
               frm.Show()


           Else

               MsgBox("Under Construction", MsgBoxStyle.Exclamation, "Technical Error")

           End If

       Catch ex As Exception

           MsgBox("El siguiente error fue detectado: " & ex.Message.ToString, MsgBoxStyle.Critical)

       End Try

       con.Close()

   End Sub

   Private Function DynamicallyLoadedObject(ByVal objectName As String, _
       Optional ByVal args() As Object = Nothing) As Form
       Dim returnObj As Object = Nothing
       Dim Type As Type = Assembly.GetExecutingAssembly().GetType( _
           "SysROCAR." & objectName)
       If Type IsNot Nothing Then
           returnObj = Activator.CreateInstance(Type, args)
       End If
       Return returnObj
   End Function

End Class



Al darle click al menu que quiero abrir me manda el error: "Referencia a objeto no establecida como instancia de un objeto".

El problema empieza en la funion SelectedChildMenu_OnClick la cual manda un parametro a la funcion DynamicallyLoadedObject quien se encarga de el ensamblado de la cadena a objeto. Espero alguien pueda ayudarme porque ya me siento frustrado ... saludos.

raul338

hubiera sido mas facil poner solo el codigo necesario.

Nunca vi la funcion DynamicallyLoadedObject, pero aca entraria perfecto el tutorial de refelction que hizo nuestro amigo danger Introduccion a System.Reflection

Leelo y nos cuentas ;)

ezugaru

Cita de: raul338 en 15 Junio 2010, 00:09 AM
hubiera sido mas facil poner solo el codigo necesario.

Nunca vi la funcion DynamicallyLoadedObject, pero aca entraria perfecto el tutorial de refelction que hizo nuestro amigo danger Introduccion a System.Reflection

Leelo y nos cuentas ;)

De hecho antes de postear vi ese tuto, sin embargo, aun no llegan a lo que estoy usando que es el manejo de tipos (Type) y a parecer ese es mi problema, ya que cuanod declaro el tipo y trato de obtener el namespace junto con el form que quiero llamar, la variable de Type sale vacía, por eso es que no funciona, y es lo que ando tratando de resolver, he visto en otros foros, el msdn, pero hay mucho que me cuesta entender y otro poco que no es lo que necesito (al menos eso creo) por eso hice el post , a ver si alguien con conocimientos mas avanzados me podía orientar al respecto.

ezugaru

Resuelto, el problema se generaba porqueel NameSpace que obtuve por alguna razon era incorrecto, al usar el  MsgBox(Me.GetType().Namespace) obtuve el namespace correcto, y me di cuenta que me falta un guion bajo, y ya con eso funciono como debe, llamandome al Form que ya tenia hecho en modo de diseño. Anexo foto :D



Gracias a todos :D por echar un vistazo.

El codigo lo resumo, y solo estoy usando 4 lineas:



Dim frmToOpen As Form = Activator.CreateInstance(Type.GetType("SysROCAR_1._0." & frmName))

                frmToOpen = DirectCast(frmToOpen, Form)

                frmToOpen.MdiParent = Me

                frmToOpen.Show()


raul338

Cita de: raul338 en 15 Junio 2010, 00:09 AM
hubiera sido mas facil poner solo el codigo necesario.

Nunca vi la funcion DynamicallyLoadedObject, ..............
Cita de: ezugaru
Código (vbnet) [Seleccionar]

    Private Function DynamicallyLoadedObject(ByVal objectName As String, _
        Optional ByVal args() As Object = Nothing) As Form
        Dim returnObj As Object = Nothing
        Dim Type As Type = Assembly.GetExecutingAssembly().GetType( _
            "SysROCAR." & objectName)
        If Type IsNot Nothing Then
            returnObj = Activator.CreateInstance(Type, args)
        End If
        Return returnObj
    End Function

Es el fail mas grande que hice en todo el foro :xD

Que bien que te haya salido!!!