2008-12-24 11 views
10

Si establece la propiedad Visible de un control de Windows Forms en verdadero, esa propiedad aún devuelve falso si alguna de las ventanas principales del control está oculta. ¿Hay alguna forma de obtener el indicador de visibilidad subyacente verdadero del control en caso de que la ventana principal esté oculta?¿Cómo obtener el valor "real" de la propiedad Visible?

Respuesta

13

Bueno, la implementación normal hace verifica la pila de control, para asegurarse de que todos los padres estén visibles. La única manera que conozco para esquivar esto es hacer trampa con la reflexión, y pedir GetState(2), pero que es frágil:

// dodgy; not recommended 
    Panel query; 
    Form form = new Form 
    { 
     Controls = { 
      new Panel { 
       Visible = false, 
       Controls = { 
        (query = new Panel {Visible = true}) 
       } 
      } 
     } 
    }; 
    form.Show(); 

    // this is the dodgy bit... 
    bool visible = (bool)typeof(Control) 
     .GetMethod("GetState", BindingFlags.Instance | BindingFlags.NonPublic) 
     .Invoke(query, new object[] { 2 }); 
+0

Gracias, votaré después de esperar por más respuestas. – Qwertie

+0

¿Qué es el 2? ¿Hay una constante o enum que puedas usar en su lugar? –

+1

@Jon, sí, existe, pero es en sí mismo interno, por lo que tendría que usar más reflexión para obtenerlo ;-p Pero es STATE_VISIBLE. –

0

Una opción que no se basa en la reflexión sería recursivo a través de los padres del control de jerarquía buscando uno con Visible establecido en falso.

EDITAR: Consulte los comentarios sobre el significado del código.

var frm2 = new Form {Text = "Form2"}; 
var lbl = new Label {Visible = true}; 
frm2.Controls.Add(lbl); 
frm2.Show(); 

var frm1 = new Form {Text = "Form1"}; 
var lblVis = new Label { Text = lbl.Visible.ToString(), Left = 10, Top = 10}; 
lbl.VisibleChanged += (sender, args) => MessageBox.Show("Label Visible changed"); 
var btnShow = new Button {Text = "Show", Left = 10, Top = lblVis.Bottom + 10}; 
btnShow.Click += (sender, args) => 
        { 
         frm2.Visible = true; 
         lblVis.Text = lbl.Visible.ToString(); 
         }; 
var btnHide = new Button {Text = "Hide", Left = 10, Top = btnShow.Bottom + 10}; 
btnHide.Click += (sender, args) => 
        { 
         frm2.Visible = false; 
         lblVis.Text = lbl.Visible.ToString(); 
        }; 

frm1.Controls.AddRange(new Control[] {lblVis, btnShow, btnHide}); 

Application.Run(frm1); 

+0

Pero eso no le dice si el original es verdadero o falso; si no hay padres invisibles, puedes (probablemente) confiar en .Visible, pero si hay * son *, no tienes ni idea de si tu control tiene (localmente) Visible = verdadero o Visible = falso –

+0

Tendrás que mirar ambos, entonces, si actualmente es visible, encontrar un padre que sea falso significaría que no es actualmente. – toad

+0

Pero Visible nunca volverá verdadero si alguno de los padres es invisible; ese es el problema: el marco ya verifica esto. Creo que el OP quiere saber si el control * localmente * piensa que es visible, es decir, si todos los padres estuvieran visibles, ¿lo sería también? No puedes encontrar esto solo por Visible. –

2

Lo que hice es quitar temporalmente el botón de su matriz controla para comprobar su valor visible y volver a añadir a los controles de los padres.

Si lo necesita, puede seguir el índice secundario para volver a agregarlo en el índice correcto.

0

Tengo el mismo problema con las clases derivadas de la clase base 'ToolStripItem'. así que usé el valor de propiedad Disponible para verificar si el elemento se mostrará o no. problema resuelto. Ejemplo:

ToolStripItem curItm = menuStrip1.Items[i] as ToolStripItem; 
if(curItm is ToolStripItem && curItm.Available) DoAnyThing(); 

En este ejemplo, 'curItm' es una instancia de la clase derivada ToolStripItem.

Este problema con las propiedades visibles/habilitadas en los controles .Net que dependen del contenedor visible/habilitado del contenedor principal debe ser resuelto por el equipo .Net. Creo una propiedad de vestuario llamada IsVisible/IsEnabled en mis propias clases que devuelven el valor asignado para las propiedades visibles/habilitadas y no el valor que depende del contenedor padre.

Cuestiones relacionadas