#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;
}
}