Как мне определить видимость элемента управления?

#c# #winforms #.net-3.5 #controls #visibility

#c# #winforms #.net-3.5 #элементы управления #видимость

Вопрос:

У меня есть TabControl , который содержит несколько вкладок. На каждой вкладке есть одна UserControl . Я хотел бы проверить видимость элемента управления x на UserControl A из UserControl B . Я полагал, что выполнение x.Visible из UserControl B было бы достаточно хорошим. Как оказалось, он отображался false в отладчике, хотя я явно установил для него значение true и оно никогда не менялось. Затем я прочитал в MSDN для Control.Visible, что:

Даже если для параметра Visible установлено значение true, элемент управления может быть не виден пользователю, если он скрыт за другими элементами управления.

К моему большому удивлению, это не сработает. Теперь мне интересно, как я могу определить, x виден ли элемент управления с другого UserControl устройства. Я бы хотел избежать использования логического значения, если это возможно. Кто-нибудь сталкивался с этим и нашел решение?

Примечание: Также кажется, что в этой ситуации Control.IsAccessible равно false.

Комментарии:

1. Вы пробовали подниматься по иерархии контейнеров и определять, что они не видны, если какой-либо из них не виден?

2. Да, для всех родительских элементов управления на всем пути вверх установлено Visible свойство false .

3. Итак, вы не видны, я прав?

4. Сам элемент управления виден, просто не виден пользователю.

5. Ну, я хочу сказать, что элемент управления ДЕЙСТВИТЕЛЬНО виден, если он и все его контейнеры видны.

Ответ №1:

К сожалению, элемент управления не предоставляет ничего общедоступного, что позволило бы вам это проверить.

Одной из возможностей было бы установить что-то в свойстве ‘Tag’ элементов управления. Цель тега — связать пользовательские данные с элементом управления. Таким образом, это может быть что угодно, а не только логическое значение.

Вот документ о свойствах тега

Если вы действительно хотите использовать метод грубой силы, вы можете использовать отражение, в основном вызывая getState(2):

 public static bool WouldBeVisible(Control ctl) 
{
      // Returns true if the control would be visible if container is visible
      MethodInfo mi = ctl.GetType().GetMethod("GetState", BindingFlags.Instance | BindingFlags.NonPublic);
      if (mi == null) return ctl.Visible;
      return (bool)(mi.Invoke(ctl, new object[] { 2 }));
}
  

Комментарии:

1. 1 хорошая находка. Похоже, нобугз (он же Ханс Пассант) опубликовал нечто подобное здесь: social.msdn.microsoft.com/Forums/en/winforms/thread /… . Спасибо за ответ!

Ответ №2:

Пожалуйста, попробуйте это:

 bool ControlIsReallyVisible(Control C)
{
    if (C.Parent == null) return C.Visible;
    else return (C.Visible amp;amp; ControlIsReallyVisible(C.Parent));
}
  

Комментарии:

1. У меня это решение не сработало. Всегда возвращает true.

2. ИМХО, это не может помочь. OP сообщает, что это x.Visible есть false . В этом случае результатом x.Visible amp;amp; any-other-code все равно будет false .

Ответ №3:

Я использую этот код, не только проверяя всех видимых предков, а также того, кто является корневым элементом управления. Проверка root необходима, когда элемент управления не добавлен в основную форму.

 public static class StratoControlExtension
{
    public static bool TruelyVisible(this Control control, Control expected_root)
    {
        if (control.Parent == null) { return control == expected_root amp;amp; control.Visible; }
        return control.Parent.TruelyVisible(expected_root) amp;amp; control.Visible;
    }
}