How to get the “real” value of the Visible property?

前端 未结 4 950
执笔经年
执笔经年 2021-01-11 11:40

If you set the Visible property of a Windows Forms control to true, that property still returns false if any of the control\'s parent windows are hidden. Is there a way to g

相关标签:
4条回答
  • 2021-01-11 11:56

    I have same issue with classes derived from 'ToolStripItem' base class. so I used Available property value to check if item will be displayed or not. problem solved. Sample:

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

    In this sample 'curItm' is an instance of of ToolStripItem derived class.

    This problem with Visible/Enabled properties in .Net controls that depend on parent container's Visible/Enabled must be solved by .Net team. I create a costume property named IsVisible/IsEnabled in my own classes that return assigned value for Visible/Enabled properties and not the value that depend on parent container.

    0 讨论(0)
  • 2021-01-11 11:59

    An option that doesn't rely on reflection would be to recurse through the parents of the control hierarchy looking for one with Visible set to false.

    EDIT: See comments for significance of 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 讨论(0)
  • 2021-01-11 12:05

    What I did is temporarily remove the button from its parent controls to check its Visible value and then re-add to the parent controls.

    If you need you can track the child index to re-add it at the right index.

    0 讨论(0)
  • 2021-01-11 12:14

    Well, the regular implementation does check up the control stack, to ensure that all parents are visible. The only way I know to dodge this is to cheat with reflection, and ask for GetState(2), but that is brittle:

        // 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 讨论(0)
提交回复
热议问题