.net - ¿Cómo obtener el valor "real" de la propiedad Visible?
winforms (4)
Una opción que no se basa en la reflexión sería recurrir a través de los padres de la jerarquía de control buscando uno con el conjunto visible en falso.
EDITAR: vea los comentarios sobre la importancia 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);
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?
Bueno, la implementación regular verifica la pila de control, para asegurar que todos los padres estén visibles. La única forma que conozco de eludir esto es hacer trampas con reflexión y pedir GetState(2)
, pero eso 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 });
Lo que hice fue quitar temporalmente el botón de sus controles principales para verificar su valor Visible y luego volver a agregarlo a los controles principales.
Si lo necesita, puede rastrear el índice secundario para volver a agregarlo en el índice correcto.
Tengo el mismo problema con las clases derivadas de la clase base ''ToolStripItem''. así que utilicé el valor de propiedad Disponible para verificar si el elemento se mostrará o no. problema resuelto. Muestra:
ToolStripItem curItm = menuStrip1.Items[i] as ToolStripItem;
if(curItm is ToolStripItem && curItm.Available) DoAnyThing();
En esta muestra, ''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 primario 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.