2008-12-24 42 views

回答

13

那麼,正常執行確實檢查控制堆棧,以確保所有父母都可見。我知道的唯一辦法逃避,這是與反思作弊,並要求GetState(2),但畢竟是易碎:

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

謝謝,我會等待更多的答案後投票。 – Qwertie 2008-12-24 18:00:07

+0

2是什麼?有沒有一個常數或枚舉可以用來代替? – 2008-12-24 18:12:13

0

不依靠反射的選擇是通過控制的父母遞歸層次結構尋找Visible設置爲false的層次結構。

編輯:查看關於代碼重要性的評論。

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); 

2

我所做的是暫時刪除按鈕從其父控制,以檢查它的Visible值,然後重新添加到父控件。

如果您需要您可以跟蹤子索引以重新添加它在正確的索引。

0

我對從'ToolStripItem'基類派生的類有同樣的問題。所以我使用可用屬性值來檢查是否顯示項目。問題解決了。示例:

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

在本示例中,'curItm'是ToolStripItem派生類的一個實例。

依賴父容器的Visible/Enabled的.Net控件中的Visible/Enabled屬性的這個問題必須由.Net團隊解決。 我在我自己的類中創建名爲IsVisible/IsEnabled的服裝屬性,該屬性爲可見/啓用屬性返回分配值,而不是依賴父容器的值。