:-(
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.
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 (http://foro.elhacker.net/vbnet/tutorial_introduccion_a_systemreflection-t295465.0.html)
Leelo y nos cuentas ;)
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 (http://foro.elhacker.net/vbnet/tutorial_introduccion_a_systemreflection-t295465.0.html)
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.
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
(http://img44.imageshack.us/img44/1339/suckmethisvbnet.th.jpg) (http://img44.imageshack.us/i/suckmethisvbnet.jpg/)
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()
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
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!!!