none
Ayuda porfavor estoy desesperado. Windows Form RRS feed

  • Pregunta

  • Hola hace unos días que empezó una aplicación con VS 2012 y cree un formulario Padre y me di a la tare de crear uno hijo llamándolo de la siguiente manera:
    Private Sub btMaquinaria_ItemClick_1(sender As Object, e As DevExpress.XtraBars.ItemClickEventArgs) Handles btMaquinaria.ItemClick
            Dim frm As New frmMaquinaria
            frm.MdiParent = Me
            frm.Show()
        End Sub

    Al hacer click en el botón maquinaria funciona perfecto llama al formulario hijo y puedo usarlo como es debido, pero ... si se vuelve a dar click en el botón llama de nuevo a un formulario totalmente nuevo no se si se diga así pero crea otra instancia y me manda otro formulario nuevo y así tantas veces de click en el botón será el numero de formularios que obtenga, pero esto no es lo que yo requiero, solo necesitó un formulario, la primera vez que haga click sobre el botón maquinaria me muestre el formulario maquinaria como hijo y si vuelvo a hacer click sobre el botón maquinaria ya no llame a otro formulario nuevo, sino que me active o me de el foco de el formulario maquinaria que ya llame eh probado con todo y no lo puedo hacer ayuda porfavor :V


    Por cierto estoy usando devExpress y no me permite hacerlo de la forma en la que no se crea la instancia solo se llama asi :

     
    formulario.MdiParent= Me
    formulario.MdiParent.Show()
    


    Solo de la otra forma.

    lunes, 14 de octubre de 2013 15:31

Todas las respuestas

  • Para no crear un objeto formulario en cada clic debes sacar la definición del formulario fuera del método.

    Pon la definición Dim frm As New frmMaquinaria a nivel del formulario

    y deja solo la llamada en el ItemClick

    frm.MdiParent = Me
    frm.Show()


    Saludos, Javier J

    lunes, 14 de octubre de 2013 16:26
  • Hola Demetrio:

     Para evitar abrir de nuevo el formulario debes de preguntar primero si esta ya se encuentra abierto, para después actuar en consecuencia:

     Enrique Mtz. nos regala un bonito ejemplo en este link:

    SABER SI UN FORMALARIO ESTA ABIERTO O CERRADO

    No olvides comentarnos como te fue y cerrar las preguntas marcando las respuestas que resuelvan tu problema y votar como útiles aquellas que te brindaron un nuevo conocimiento.


    Saludos desde Monterrey, Nuevo León, México!!!

    • Propuesto como respuesta Sergio Parra lunes, 14 de octubre de 2013 17:16
    lunes, 14 de octubre de 2013 17:06
  • Saludos y gracias por tu respuesta pero ya eh tratado así y no me lo permite, bueno lo que entendí que sugieres que haga es no poner la definición? cierto algo como por ejemplo si mi formulario hijo se llama frmHijo y el botón para llamarlo fuera btnfrmHijo tu me sugieres que solo se alago así??

    Private Sub btnfrmHijo_ItemClick_1(sender As Object, e As DevExpress.XtraBars.ItemClickEventArgs) 
    
    frmHijo.MdiParent=Me
    frmHijo.show()
    
    end Sub

    La cuestión es que no me lo permite así creo que por que estoy usando DevExpress no me deja hacerlo y es necesario que lo use por ello me veo obligado a poner la instancia del formulario:

    Dim frm as New frmHijo

    por que de otra forma no me permite llamarlo.


    lunes, 14 de octubre de 2013 23:41
  • Hola Gracias por tu respuesta eh tratado de hacer la función que trae el ejemplo:
    SABER SI UN FORMALARIO ESTA ABIERTO O CERRADO

    Pero no me deja me marca un error en:

    ForEachfrm AsFormInMy.Application.OpenForms

    Diciendo que My.Application.OpenForms  no es miembro. trate de importar el System.Windows.Form y no se puede.

    Estoy usando visual studio 2012 y al parecer la solución es para el 2008.



    lunes, 14 de octubre de 2013 23:47
  • Hola.

     podrías subir el código que estas probando por favor...


    Saludos desde Monterrey, Nuevo León, México!!!

    martes, 15 de octubre de 2013 3:10
  • Hola gracias a todos por su interés y ayuda ciertamente me fue muy útil después de tratar y tratar eh llegado a la conclusión que es imposible de hacer sin tener que meterse a la programación avanzada, esto es por que uso librerías de https://www.devexpress.com/  y creo yo que no permiten la herencia típica de Windows forms  por ello no me deja simplemte hacerlo como estaba acostumbrando:

    frmhijo.MdiParent = Me
    frmHijo.Show()

    Siempre los había llamado de esta forma sin tener que instanciar nada ( Dim frm As New frmHijo ) y para resolver mi problema y ya no complicarme tanto cree un modulo con banderas para controlar que al dar click sobre el boton solo me habrá un formulario, aun no encuentro como poner el foco sobre el formulario abierto al volver a dar click  sobre el botón.

    También me encuentro con otro problema nuevo cuando quiero utilizar algún miembro del formulario abierto no puedo por que para ello creo otra instancia, es decir:

    Suponiendo que txtboxValor es del formulario Padre y txtboxDato es del formulario hijo, antes yo lo manejaba así:  
    txtboxValor.Text=frmHijo.txtboxDato.Text

    Pero ahora no me permite hacer la referencia "directa" para hacerlo debo crear una instancia:

    Dim frm As New frmHijo
    txtboxValor.Text=frm.txtboxDato.Text

    Pero precisamente como el problema de ello es que me crea una nueva referencia de un nuevo formulario el formulario sencillamente no hace nada, por ello estoy planeando manejarlo todo con una clase auxiliar.

    Si alguno supiera como evitar todo eso se los agradecería mucho por el momento dejo el código de la forma que resolví el problema de lo formularios infinitos, aun no hayo como darle foco al formulario ya invocado.

    Clase principal.

    Imports System.ComponentModel
    Imports System.Text
    
    Partial Public Class frmPrincipal
        Inherits DevExpress.XtraBars.Ribbon.RibbonForm
    
        Public Sub New()
            InitializeComponent()
        End Sub
    Private Sub btMaquinaria_ItemClick_1(sender As Object, e As DevExpress.XtraBars.ItemClickEventArgs) Handles btMaquinaria.ItemClick
            If bandMaq Then
                Dim frm As New frmMaquinaria
                frm.MdiParent = Me
                frm.Show()
                bandMaq = False
            End If
        End Sub
     End Class
    
    Modulo Auxiliar.

    Module ModuloAux
        
        Public bandMaq As Boolean = True
       
    End Module

    Y mi intento fallido por pasarle el foco, es fallido por que despues de el else me marca a frm como no declarada pero como podran ver la declaro justo arriba y el nivel de variable es en al funcion.

     Private Sub btMaquinaria_ItemClick_1(sender As Object, e As DevExpress.XtraBars.ItemClickEventArgs) Handles btMaquinaria.ItemClick
            If bandMaq Then
                Dim frm As New frmMaquinaria
                frm.MdiParent = Me
                frm.Show()
                bandMaq = False
             Else
                frm.Focus() 'Aquí me marca frm No esta clarado.Puede que no este acciseble debido a su nivel de proteccion
            End If
        End Sub

    De ante mano muchas gracias.
    martes, 15 de octubre de 2013 14:27
  • Para eso puedes usar el patron Singleton. Es muy simple.

    Creas un nuevo formulario ShowForm(reemplazar por el nombre de tu form) y le pones el siguiente código

    public sealed partial class ShowForm : Form
        {
            private static readonly ShowForm MyInstance = new ShowForm();
            private static bool IsShown = false;
            
            private ShowForm()
            {
                InitializeComponent();
            }

            public static ShowForm OnlyInstance
            {
                get { return MyInstance; }
            }

            public new void Show()
            {
                if (IsShown)
                {
                    base.Show();
                    base.Focus();
                }
                else
                {
                    base.Show();
                    IsShown = true;
                }
            }

            static ShowForm()
            {
                OnlyInstance.FormClosing += new FormClosingEventHandler(OnlyInstance_FormClosing);
            }

            private static void OnlyInstance_FormClosing(object sender, FormClosingEventArgs e)
            {
                e.Cancel = true;
                IsShown = false;

                OnlyInstance.Hide();
            }
        }

    Desde tu form principal declaras una variable del mismo tipo que el form a mostrar y llamas al form desde el evento click del boton.

    public partial class Main : Form
        {
            private ShowForm showForm;
            
            public Main()
            {
                InitializeComponent();
            }

            private void showButton_Click(object sender, EventArgs e)
            {
                showForm = ShowForm.OnlyInstance;
                showForm.Show();
            }

        }

    y listo.

    Suerte!!!


    Juan Manuel Gómez Meza Analista Desarrollador C#

    jueves, 7 de noviembre de 2013 14:50