Модераторы: Partizan, gambit
  

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Как определить отображается ли control, есть ли в текущий момент на экране 
V
    Опции темы
elsan
Дата 20.7.2011, 12:09 (ссылка) |    (голосов:1) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 24
Регистрация: 23.5.2007
Где: Томск

Репутация: нет
Всего: нет



Добрый день.

Есть TabControl на вкладках, которого расположены TextBox. При переключении вкладок нужно выставить флаг, что некоторые  TextBox не отображаются и информацию в них обновлять не нужно. Вариант ловить событие изменения вкладок не желателен.
Какое событие или фукнция возвращает состояние контрола, выведен он на экран или нет?

VisibleChanged срабатывает только при Visible=true. Может кто-то сталкивался с подобным.
Спасибо.
PM MAIL   Вверх
AlexNagits
  Дата 20.7.2011, 18:01 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 13
Регистрация: 14.7.2011

Репутация: нет
Всего: нет



Привет, elsan!

Цитата(elsan @  20.7.2011,  12:09 Найти цитируемый пост)
Есть TabControl на вкладках, которого расположены TextBox

Из-за запятой я только с 5 раза понял смысл предложения  smile 

А вопрос очень даже хороший. Я бы его запостил в разделе "не для новичков". 
Ясно, что про Visible надо вообще забыть. Можно скрыть элемент с экрана многими способами и Visible останется true.

За часок-другой набросал решение в виде класса ReallyVisibility, проверил для разных случаев скрытия элемента с экрана:
    Скрытие элемента прокруткой скроллбара
    Скрытие элемента перелистыванием TabPage
 - работает, однако возможны ошибки, так что имейте ввиду.

Код

public static class ReallyVisibility
    {
        public static bool Visible(Control control)
        {
            if (!control.Visible)
                return false; //если Visible == false, то и проверять нечего

            List<Control> parentList = GetComponentTree(control);
            foreach (Control controlInTree in parentList)
            {
                if (!ChildVisibleRespectParent(controlInTree))
                    return false;
            }

            return true;
        }

        private static List<Control> GetComponentTree(Control child)
        {
            List<Control> parentList = new List<Control>();
            parentList.Add(child);

            Control parent = child.Parent;
            while (parent != null)
            {
                parentList.Add(parent);
                parent = parent.Parent;
            }
            parentList.Reverse();
            return parentList;
        }

        //Видимость child-а относительно его родителя
        private static bool ChildVisibleRespectParent(Control child)
        {
            if (!child.Visible)
                return false; //если Visible == false, то и проверять нечего

            Control parent = child.Parent;
            if (parent == null)
                return child.Visible;


            Point childScreenPoint = child.PointToScreen(Point.Empty);
            Point pos = parent.PointToClient(childScreenPoint);
            List<Point> childPointList = GetChildKeyPoints(child, pos);

            foreach (Point childPoint in childPointList)
            {
                Control childAtPoint = parent.GetChildAtPoint(childPoint);

                #region parent is TabControl?
                //Выход из ситуации, когда при любом tabControl.SelectedIndex 
                //tabControl.GetChildAtPoint всегда возвращает tabControl.TabPages[0]
                if (parent is TabControl)
                {
                    TabControl tabControl = (TabControl)parent;
                    if (tabControl.TabPages.Count != 0 && childAtPoint == tabControl.TabPages[0] && tabControl.SelectedIndex != 0)
                    {
                        childAtPoint = tabControl.SelectedTab;
                    }
                }
                #endregion

                if (childAtPoint == child)
                    return true;
            }

            return false;
        }

        //Какие точки будем проверять?
        private static List<Point> GetChildKeyPoints(Control child, Point pos)
        {
            List<Point> childPointList = new List<Point>();

            #region Проверка для "прямоугольных" компонентов
            childPointList.Add(pos); //левый верхний угол
            childPointList.Add(new Point(pos.X + child.Width - 1, pos.Y)); //правый верхний угол
            childPointList.Add(new Point(pos.X, pos.Y + child.Height - 1)); //нижний левый угол
            childPointList.Add(new Point(pos.X + child.Width - 1, pos.Y + child.Height - 1)); //правый нижний угол
            #endregion

            #region Проверка для компонентов другой формы (овал может быть?)
            childPointList.Add(new Point(pos.X + child.Width / 3, pos.Y + child.Height / 3)); //левый верхний угол
            childPointList.Add(new Point(pos.X + child.Width / 2, pos.Y + child.Height / 2)); //середина
            childPointList.Add(new Point(pos.X + child.Width / 3 * 2, pos.Y + child.Height / 3 * 2)); //правый нижний угол
            #endregion

            return childPointList;
        }


Как пользоваться:
Код

bool reallyVisible = ReallyVisibility.Visible(textBox1);


Это сообщение отредактировал(а) AlexNagits - 20.7.2011, 18:06

Присоединённый файл ( Кол-во скачиваний: 4 )
Присоединённый файл  ControlScreenVisibility.cs 4,09 Kb
PM MAIL   Вверх
Экскалупатор
Дата 20.7.2011, 18:31 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Завсегдатай
Сообщений: 1746
Регистрация: 1.4.2009
Где: г. Минск

Репутация: 5
Всего: 24



Цитата(elsan @  20.7.2011,  11:09 Найти цитируемый пост)
Вариант ловить событие изменения вкладок не желателен.

интересно чем вызвано подобное ограничение? вполне логично было бы считать что если таб не активен то и контролы не видны...
PM MAIL ICQ   Вверх
elsan
  Дата 21.7.2011, 07:13 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 24
Регистрация: 23.5.2007
Где: Томск

Репутация: нет
Всего: нет



Спасибо большое за конкретную реализацию. smile Сейчас буду пробовать применить.
Цитата

интересно чем вызвано подобное ограничение? вполне логично было бы считать что если таб не активен то и контролы не видны...

Да верно, но компоненты которые используются для построения - UserControl, и хотелось бы чтобы все свойства и события были у них универсальными насколько возможно, а не привязывались к конкретной задаче. Планируется сделать свою библиотеку. 

Спасибо за быстрый ответ.
PM MAIL   Вверх
  
Ответ в темуСоздание новой темы Создание опроса
Прежде чем создать тему, посмотрите сюда:
Partizan
PashaPash

Используйте теги [code=csharp][/code] для подсветки кода. Используйтe чекбокс "транслит" если у Вас нет русских шрифтов.
Что делать если Вам помогли, но отблагодарить помощника плюсом в репутацию Вы не можете(не хватает сообщений)? Пишите сюда, или отправляйте репорт. Поставим :)
Так же не забывайте отмечать свой вопрос решенным, если он таковым является :)


Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, mr.DUDA, Partizan, PashaPash.

 
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | .NET для новичков | Следующая тема »


 




[ Время генерации скрипта: 0.0444 ]   [ Использовано запросов: 22 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.