Обсуждение статьи "DoEasy. Элементы управления (Часть 19): Прокрутка вкладок в элементе TabControl, события WinForms-объектов"

 

Опубликована статья DoEasy. Элементы управления (Часть 19): Прокрутка вкладок в элементе TabControl, события WinForms-объектов:

В статье создадим функционал для прокрутки заголовков вкладок в элементе управления TabControl при помощи кнопок управления прокруткой. Функционал будет работать для расположения заголовков вкладок в одну строку с любой из сторон элемента управления.

Скомпилируем советник и запустим его на графике:


Как видим, всё, что хотели сегодня сделать — всё работает, как и задумывалось.

Есть две недоработки: если навести курсор на область заголовка вкладки, которая скрыта, то заголовок реагирует изменением цвета, как будто он в этом месте видимый. Это причина того, что активная область элемента не меняет своих размеров при изменении размеров видимой области. Для исправления нужно будет рассчитывать и менять размеры активной области в соответствии с видимой.

Вторая недоработка — если сместить выбранный заголовок за пределы контейнера и переместить панель, то два пикселя скрытого заголовка отобразятся. Это связано с указанием размеров вкладки для расчёта области видимости, так как выбранный заголовок увеличивается в размерах с каждой стороны на два пикселя. Для исправления нужно продумать как внутри объекта-заголовка вкладки получать размер соседнего заголовка, по которому и рассчитывать размеры области видимости.

Автор: Artyom Trishkin

 
Ничего себе. Удобная штука. Такие перспективы использования. 
Надо другие статьи из цикла глянуть. 
Автору спасибо
 

При перемещении мыши и прокрутки колёсика над панелью, может иногда прокручиваться сам график.

Как однозначно получить созданный элемент? Если у нас до этого уже были элементы типа GRAPH_ELEMENT_TYPE_WF_TAB_CONTROL, то использование индекса 0 будет не верным.

pnl.CreateNewElement(GRAPH_ELEMENT_TYPE_WF_TAB_CONTROL,InpTabControlX,InpTabControlY,pnl.Width()-30,pnl.Height()-40,clrNONE,255,true,false);
CTabControl *tc=pnl.GetElementByType(GRAPH_ELEMENT_TYPE_WF_TAB_CONTROL,0);

Дальше... Получили id заголовка интересующей вкладки:

int my_id=-1;
...
CTabHeader *th=tc.GetElementByType(GRAPH_ELEMENT_TYPE_WF_TAB_HEADER,4);
my_id=th.ID();

Ловим событие изменения активной вкладки, точнее, событие клика на заголовке. При клике на активной вкладке событие всёравно генерируется.

if((id-CHARTEVENT_CUSTOM==WF_CONTROL_EVENT_TAB_SELECT)&&(lparam==my_id))
     {
      Print(sparam);
     }

А теперь как получить объект активного поля? Это ведь CTabField?

Как узнать родительский объект?

 
Aliaksandr Hryshyn #:

При перемещении мыши и прокрутки колёсика над панелью, может иногда прокручиваться сам график.

Как однозначно получить созданный элемент? Если у нас до этого уже были элементы типа GRAPH_ELEMENT_TYPE_WF_TAB_CONTROL, то использование индекса 0 будет не верным.

Дальше... Получили id заголовка интересующей вкладки:

Ловим событие изменения активной вкладки, точнее, событие клика на заголовке. При клике на активной вкладке событие всёравно генерируется.

А теперь как получить объект активного поля? Это ведь CTabField?

Как узнать родительский объект?

1.   Индекс 0 используется для самого первого созданного прикреплённого объекта к элементу. Индекс 1 - для второго, индекс 2 - для третьего, и т.д.

2.   Можно получить поле из полученного заголовка по интересующему индексу:

         //--- Создадим элемент управления TabControl
         pnl.CreateNewElement(GRAPH_ELEMENT_TYPE_WF_TAB_CONTROL,InpTabControlX,InpTabControlY,pnl.Width()-30,pnl.Height()-40,clrNONE,255,true,false);
         CTabControl *tc=pnl.GetElementByType(GRAPH_ELEMENT_TYPE_WF_TAB_CONTROL,0);
         if(tc!=NULL)
           {
            CTabHeader *th=tc.GetTabHeader(index);
            CTabField  *tf=th.GetFieldObj();
           }

2.1  Можно получить поле вкладки из объекта TabControl по интересующему индексу:

         //--- Создадим элемент управления TabControl
         pnl.CreateNewElement(GRAPH_ELEMENT_TYPE_WF_TAB_CONTROL,InpTabControlX,InpTabControlY,pnl.Width()-30,pnl.Height()-40,clrNONE,255,true,false);
         CTabControl *tc=pnl.GetElementByType(GRAPH_ELEMENT_TYPE_WF_TAB_CONTROL,0);
         if(tc!=NULL)
           {
            CTabField  *tf=tc.GetTabField(index);
           }

3.   Не совсем понял вопрос. Если нужно узнать к какому объекту привязан текущий, то должно так работать:

      pnl=engine.CreateWFPanel("WinForms Panel"+(string)i,(i==0 ? 50 : 70),(i==0 ? 50 : 70),410,200,array_clr,200,true,true,false,-1,FRAME_STYLE_BEVEL,true,false);
      if(pnl!=NULL)
        {
         pnl.Hide();
         Print(DFUN,"Описание панели: ",pnl.Description(),", Тип и имя: ",pnl.TypeElementDescription()," ",pnl.Name());
         //--- Установим значение Padding равным 4
         pnl.SetPaddingAll(3);
         //--- Установим флаги перемещаемости, автоизменения размеров и режим автоизменения из входных параметров
         pnl.SetMovable(InpMovable);
         pnl.SetAutoSize(InpAutoSize,false);
         pnl.SetAutoSizeMode((ENUM_CANV_ELEMENT_AUTO_SIZE_MODE)InpAutoSizeMode,false);
   
         //--- Создадим элемент управления TabControl
         pnl.CreateNewElement(GRAPH_ELEMENT_TYPE_WF_TAB_CONTROL,InpTabControlX,InpTabControlY,pnl.Width()-30,pnl.Height()-40,clrNONE,255,true,false);
         CTabControl *tc=pnl.GetElementByType(GRAPH_ELEMENT_TYPE_WF_TAB_CONTROL,0);
         if(tc!=NULL)
           {
            CTabField  *tf=tc.GetTabField(index);  // Получаем поле вкладки из элемента TabControl tc
            CWinFormBase *base=tf.GetBase();       // Узнаём базовый объект для поля вкладки - должен быть TabControl tc
            CWinFormBase *main=tf.GetMain();       // Узнаём главный объект для поля вкладки - должен быть CPanel pnl
           }

Если так не возвращает указанные в комментариях объекты, то это баг, и нужно дорабатывать