2008-12-24 6 views
10

Si vous définissez la propriété Visible d'un contrôle Windows Forms sur true, cette propriété renvoie toujours false si l'une des fenêtres parent du contrôle est masquée. Est-il possible d'obtenir le vrai indicateur de visibilité sous-jacent du contrôle dans le cas où la fenêtre parente est cachée?Comment obtenir la "vraie" valeur de la propriété Visible?

Répondre

13

Eh bien, la mise en œuvre régulière ne vérifier la pile de contrôle, afin d'assurer que tous les parents sont visibles. La seule façon que je sais esquiver est de tricher avec la réflexion, et demander GetState(2), mais qui est fragile:

// 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

Merci, je vais voter après avoir attendu plus de réponses. – Qwertie

+0

Qu'est ce que le 2? Y a-t-il une constante ou une énumération que vous pouvez utiliser à la place? –

+1

@Jon, oui, il y a - mais il est lui-même interne, donc vous devrez utiliser plus de réflexion pour l'obtenir ;-p Mais c'est STATE_VISIBLE. –

0

Une option qui ne repose pas sur la réflexion serait de récursivité par les parents du contrôle hiérarchie recherchant un avec Visible défini sur false.

EDIT: Voir les commentaires pour la signification du code.

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

Mais cela ne vous dit pas si l'original est vrai ou faux; s'il n'y a pas de parents invisibles, vous pouvez (probablement) faire confiance à .Visible, mais s'il y a *, vous n'avez aucune idée si votre contrôle a (localement) Visible = true ou Visible = false –

+0

Vous devriez regarder les deux, Donc, si actuellement trouver un parent qui est faux signifierait que ce n'est pas le cas actuellement. – toad

+0

Mais Visible ne retournera jamais vrai si un parent est invisible; c'est le problème: le framework vérifie déjà cela. Je pense que le PO veut savoir si le contrôle * local * pense qu'il est visible, c'est-à-dire si tous les parents étaient visibles, le serait-il aussi? Vous ne pouvez pas trouver cela uniquement par Visible. –

2

Ce que je l'ai fait est de retirer temporairement le bouton de son contrôle parent pour vérifier sa valeur visible, puis ajouter à nouveau aux commandes des parents.

Si vous avez besoin, vous pouvez suivre l'index des enfants pour le rajouter à l'index de droite.

0

J'ai le même problème avec les classes dérivées de la classe de base 'ToolStripItem'. J'ai donc utilisé la valeur de propriété disponible pour vérifier si l'élément sera affiché ou non. problème résolu. Exemple:

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

Dans cet exemple, 'curItm' est une instance de la classe dérivée ToolStripItem.

Ce problème avec les propriétés Visible/Activé dans les contrôles .Net qui dépendent de Visible/Activé du conteneur parent doit être résolu par l'équipe .Net. Je crée une propriété de costume nommée IsVisible/IsEnabled dans mes propres classes qui renvoie la valeur affectée pour les propriétés Visible/Enabled et non la valeur qui dépend du conteneur parent.

Questions connexes