elhacker.net cabecera Bienvenido(a), Visitante. Por favor Ingresar o Registrarse
¿Perdiste tu email de activación?.

 

 


Tema destacado: Estamos en la red social de Mastodon


+  Foro de elhacker.net
|-+  Programación
| |-+  Programación General
| | |-+  .NET (C#, VB.NET, ASP) (Moderador: kub0x)
| | | |-+  MenuStrip
0 Usuarios y 1 Visitante están viendo este tema.
Páginas: [1] Ir Abajo Respuesta Imprimir
Autor Tema: MenuStrip  (Leído 3,007 veces)
SilverLycan68

Desconectado Desconectado

Mensajes: 10


Ver Perfil
MenuStrip
« en: 21 Julio 2018, 00:42 am »

Tengo un MDIParent con un menustrip y al darle click en un item me abre una nueva forma con otro menustrip que lleno con una funcion.
Problema 1: es que al abrir mas de un form solo se llena el menustrip del primero.

 MDIParent:
Código:
Public Class MDI_principal
   Private Sub MenuStrip_ItemClicked(sender As Object, e As ToolStripItemClickedEventArgs) Handles MenuStrip.ItemClicked
        Try
            Dim form As New frmSubMenus
            form.MdiParent = Me
            form.Text = e.ClickedItem.Text
            form.Show()
        Catch ex As Exception
            MsgBox("ERROR." + ex.Message)
        End Try
    End Sub
End Class

Form hijo. Si quito el MsgBox(str) no llena el menu:
Código:
Public Class frmSubMenus
    Private Sub frmSubMenus_Load(sender As Object, e As EventArgs) Handles MyBase.Load
        For Each ctr As Control In Me.Controls
            Me.ToolTip1.SetToolTip(ctr, ctr.ToString)
        Next
        Try
            Dim submenu As New ArrayList()
            submenu = MenuSecundario(Me.Text)
            If Not IsNothing(submenu) Then
                For Each str As String In submenu
                    MsgBox(str)
                    MenuStrip1.Items.Add(str)
                Next
            End If
        Catch ex As Exception
            MsgBox("ERROR." + vbLf + ex.Message + vbLf + ex.ToString)
        End Try
 End Sub

Funcion para llenar menu del form hijo:
Código:
Public Function MenuSecundario(ByVal txt As String) As ArrayList
        Dim submenu As ArrayList = Nothing
        Select Case txt
            Case "Ventas"
                submenu = New ArrayList
                submenu.Add("Cotizacion")
                submenu.Add("Pedidos")
                submenu.Add("Clientes")
                submenu.Add("por Autorizar")
                submenu.Add("Calendario")
                submenu.Add("Estadisticas")
                Exit Select

           Case "Compras"
                submenu = New ArrayList
                submenu.Add("Pendientes")
                submenu.Add("Administrador")
                submenu.Add("Productos")
                submenu.Add("Proveedores")
                submenu.Add("Clientes")
                submenu.Add("Calendario")
                submenu.Add("Estadisticas")
                Exit Select

            Case Else
                Exit Select

        End Select
        Return submenu
    End Function

Me harian el favor de decirme donde tengo el error.


En línea

Serapis
Colaborador
***
Desconectado Desconectado

Mensajes: 3.391


Ver Perfil
Re: MenuStrip
« Respuesta #1 en: 21 Julio 2018, 15:45 pm »

Al margen de que el código no es óptimo, no hay nada ilegal en él...

El comentario (siguiente, el tachado) es erróneo (aparece el constructor de clase, que pasé por alto). No obstante, tras su declaración la función llamada lo creará si lo precisa, luego sobra hacerlo aquí y por tanto basta su declaración: Dim submenu As ArrayList


(excepto que en esta línea declaraste un array de arraylist, y sobra como array, es decir elimina los paréntesis)
Dim submenu As New ArrayList()


Lo que sucede es que posiblemente no entiendas el formulario MDI.
Un formulari MDI, siempre subsume el menú,  del formulario hijo en su propio menú.
bueno siempre no... Esto está controlado por la propiedad AllowMerge del menustrip. (Abajo del todo, en la última sección, te pongo un ejemplo para dicho caso, son cambios ligeros)

Así cuando tú seleccionas Ventas, se crea el formulario con los menús asociados a él, y lo mismo con Compras... (o con alguno más si añadieras más), pero una vez que (por ejemplo) 'Ventas' tiene el foco, su menú se integra en el padre. A su vez el formulario hijo que pierde el foco (por ejemplo "Compras"), ve de vuelta su menú sobre sí, siendo retirado del formulario padre...

Una forma de verlo muy muy claro, es añadir el siguiente código al frmSubmenus
Haciendo que el formulario hijo ocupe toda el área cliente del formulario padre, no habría sitio para el menú del hijo...
Código
  1. Private Sub frmSubmenus_GotFocus(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.GotFocus
  2.        Me.WindowState = FormWindowState.Maximized
  3.    End Sub
  4.  

Y eso es todo...




A continuación, lo que te presento es algunas correciones...

En VB, no hay "BREAK", para los bloques de control "select case", luego las sentencias 'Exit select', sobran si ya se llegó al final del código del propio 'case'.
Tampoco tiene sentido llamar al araylist 'submenú... conforme a la función simplemente genera una lista, luego no tiene sentido darle un nombre más propio que lista. Tampoco es necesario asignarlo Nothing, si luego lo vas a crear...
de hecho el 'case else' sobra, y se pone solo por lo molesto del 'warning'... aunque el propio compilador ya detectaría que como de entrada es nothing, eso es lo que devuelve y que por tanto el warning, es absurdo...
Código
  1. Public Function MenuSecundario(ByVal txt As String) As ArrayList
  2.        Dim lista As ArrayList
  3.        Select Case txt
  4.            Case "Ventas"
  5.                lista = New ArrayList
  6.                lista.Add("Cotizacion")
  7.                lista.Add("Pedidos")
  8.                lista.Add("Clientes")
  9.                lista.Add("por Autorizar")
  10.                lista.Add("Calendario")
  11.                lista.Add("Estadisticas")
  12.            Case "Compras"
  13.                lista = New ArrayList
  14.                lista.Add("Pendientes")
  15.                lista.Add("Administrador")
  16.                lista.Add("Productos")
  17.                lista.Add("Proveedores")
  18.                lista.Add("Clientes")
  19.                lista.Add("Calendario")
  20.                lista.Add("Estadisticas")
  21.            Case Else
  22.                lista = Nothing
  23.        End Select
  24.        Return lista
  25.    End Function
  26.  

en el siguiente código hay 3 cosas que decir...
1- submenu es un objeto arraylist, la función llamada lo creará si lo precisa, luego sobra hacerlo aquí, basta su declaración.
2- El try...catch, carece de sentido, la línea "If Not IsNothing(submenu) Then" ya previene el posible error que pudiera ser generado, el recorrido de la lista como se hace con 'for each' no va a generar error', lo mismo que añadir ítems al menu... ahí el único error posible es que no existiera el menustrip1. Algo que se va a detectar en diseño, a poco que se pruebe el proyecto... luego poner try....catch, donde no son necesarios es una práctica lastrante.
3 - El msgbox, también sobra, aunque en diseño, para probar puedes ponerlo, de todas manearas unas décimas de segundo, después se podrá ver sobre la ventana MDI, luego...
Código
  1. Private Sub frmSubMenus_Load(ByVal sender As Object, ByVal e As EventArgs) Handles MyBase.Load
  2.        For Each ctr As Control In Me.Controls
  3.            Me.ToolTip1.SetToolTip(ctr, ctr.ToString)
  4.        Next
  5.        'Try
  6.        Dim submenu As ArrayList  
  7.        submenu = MenuSecundario(Me.Text)
  8.        If Not IsNothing(submenu) Then
  9.            For Each str As String In submenu
  10.                'MsgBox(str)
  11.                MenuStrip1.Items.Add(str)
  12.            Next
  13.        End If
  14.        'Catch ex As Exception
  15.        'MsgBox("ERROR." + vbLf + ex.Message + vbLf + ex.ToString)
  16.        'End Try
  17.    End Sub
  18.  

En esta sección, hemos movido la declaración del form al módulo de clase, fuera de la funcionalidad del evento.
El try...catch, también sobra, pero puedes mantenerlo mientras lo pruebas, antes de compilar, coméntal dichas líneas...
Lo más importante... como no has limitado de ninguna manera que pueda seguir creando más formularios 'Ventas, 'Compras'...cada vez que pulses en el menuStrip "Ventas", ó "Compras", generarás un nuevo formulario, cada uno con su propio menú, el problema es que no sabrás distinguir uno de otro...
Entonces o bien limitas a que solo se cree un único menú de cada tipo o bien 'personaliza el nombre' para cada uno...
La forma más simple de personalizar el nombre, es autonumerarlos... Es el código que añado sobre lo que tú tienes...
Código
  1. Dim form As frmSubmenus
  2.  
  3.    Private Sub MenuStrip_ItemClicked(ByVal sender As System.Object, ByVal e As System.Windows.Forms.ToolStripItemClickedEventArgs) Handles MenuStrip.ItemClicked
  4.        Static childrens As Int16
  5.        Try
  6.            form = New frmSubmenus
  7.            form.MdiParent = Me
  8.            form.Text = e.ClickedItem.Text & "-" & childrens.ToString
  9.            form.Show()
  10.            childrens += 1
  11.        Catch ex As Exception
  12.            MsgBox("ERROR." + ex.Message)
  13.        End Try
  14.    End Sub
  15.  




p.d.: añado los cambios para que cada formulario porte su propio menú... de forma independiente.

Ahora si tu prefieres que cada menú hijo tenga su propio menú sobre sí, y no subsumido en el 'padre', tienes que hacer estos cambios:

Ve a las propiedades del formulario MDI, selecciona el objeto MenuStrip1, cambia su propiedad
 AllowMerge del menustrip1 a FALSE

Y ahora cambia el código en cada formulario según el code de cada uno que pongo a continuación...

Código
  1. Private Sub frmSubMenus_Load(ByVal sender As Object, ByVal e As EventArgs) Handles MyBase.Load
  2.        Dim submenu As ArrayList
  3.  
  4.        For Each ctr As Control In Me.Controls
  5.            Me.ToolTip1.SetToolTip(ctr, ctr.ToString)
  6.        Next
  7.  
  8.  
  9.        ' Como ahora el texto de cada formulario está autonemuerado (pero comenzando con un guión)
  10.        ' Tomamos la parte común del nombre...
  11.        ' Esto tendría más fácil solución si en vez de pasar un string, se pasara un valor numérico
  12.        ' por ejemplo:   (1=Ventas, 2=compras, otro=else) partiendo quizás de una enumeración...
  13.        Dim strName As String
  14.        Dim k As Integer = InStr(Me.Text, "-")
  15.        If (k > 0) Then
  16.            strName = Me.Text.Substring(0, k - 1)
  17.        Else
  18.            strName = Me.Text
  19.        End If
  20.  
  21.        submenu = MenuSecundario(strName)
  22.        If Not IsNothing(submenu) Then
  23.            For Each str As String In submenu              
  24.                Me.MenuStrip1.Items.Add(str)
  25.            Next        
  26.        End If        
  27.    End Sub
  28.  

El autonumerado sigue válido para el caso, así verás más ventanas del mismo tipo cada una con su propio menú... (esto es copia del código del último bloque antes de la linea de sección).
Código
  1. Dim form As frmSubmenus
  2.  
  3.    Private Sub MenuStrip_ItemClicked(ByVal sender As System.Object, ByVal e As System.Windows.Forms.ToolStripItemClickedEventArgs) Handles MenuStrip.ItemClicked
  4.        Static childrens As Int16
  5.        Try
  6.            form = New frmSubmenus
  7.            form.MdiParent = Me
  8.            form.Text = e.ClickedItem.Text & "-" & childrens.ToString
  9.            form.Show()
  10.            childrens += 1
  11.        Catch ex As Exception
  12.            MsgBox("ERROR." + ex.Message)
  13.        End Try
  14.    End Sub
  15.  

Y si tienes activado El windowSTate Maximized... tendrás otra línea de menú bajo el principal, prueba con y sin estas líneas...
Código
  1. Private Sub frmSubmenus_GotFocus(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.GotFocus
  2.        Me.WindowState = FormWindowState.Maximized
  3.    End Sub
  4.  





Aún así, debrrías limitar la creación de formularios, no es tolerable que cada vez que se pulse el menú, se cree una nueva ventana, porque durante una sesión un mismo menú podría ser pulsado 50 veces, crear 50 formularios... seguramente no sea necesario, creo que es algo que dejas abierto y no es adecuado.  Como mínimo habría que eliminar el formulario previo del mismo tipo...


« Última modificación: 29 Julio 2018, 16:46 pm por NEBIRE » En línea

Páginas: [1] Ir Arriba Respuesta Imprimir 

Ir a:  

WAP2 - Aviso Legal - Powered by SMF 1.1.21 | SMF © 2006-2008, Simple Machines