Diskussion zum Artikel "DoEasy. Steuerung (Teil 19): Verschieben der Registerkarten in TabControl, Ereignisse im WinForms-Objekt"

 

Neuer Artikel DoEasy. Steuerung (Teil 19): Verschieben der Registerkarten in TabControl, Ereignisse im WinForms-Objekt :

In diesem Artikel werde ich die Funktionsweise zum Verschieben (scrolling) von Registerkartenüberschriften in TabControl mithilfe von Scroll-Schaltflächen erstellen. Die Funktionalität ist dazu gedacht, Tabulator-Kopfzeilen in einer einzigen Zeile auf beiden Seiten des Steuerelements zu platzieren.

Kompilieren Sie den EA und starten Sie ihn auf einem Chart:


Wie wir sehen können, funktioniert alles wie vorgesehen.

Es gibt jedoch zwei Unzulänglichkeiten: Wenn man mit dem Mauszeiger über den ausgeblendeten Kopfbereich der Registerkarte fahren, ändert die Kopfzeile ihre Farbe, als ob sie in diesem Bereich sichtbar wäre. Aus diesem Grund ändert sich die Größe des aktiven Bereichs des Steuerelements nicht, wenn die Größe des sichtbaren Bereichs geändert wird. Um dies zu beheben, muss ich den aktiven Bereich berechnen und in der Größe an den sichtbaren Bereich anpassen.

Die zweite Unzulänglichkeit besteht darin, dass zwei Pixel der ausgeblendeten Kopfzeile angezeigt werden, wenn man die ausgewählte Kopfzeile außerhalb des Containers bewegen und das Bedienfeld verschieben. Dies hat mit der Größenbestimmung der Registerkarte für die Bereichsberechnung zu tun, da die ausgewählte Kopfzeile auf jeder Seite um zwei Pixel größer wird. Um dies zu beheben, muss ich eine Möglichkeit finden, die Größe der angrenzenden Kopfzeile innerhalb des Registerkartenkopf-Objekts zu ermitteln, anhand derer die Größe des Sichtbarkeitsbereichs berechnet wird.

Autor: Artyom Trishkin

 
Wow! Das ist praktisch. So viel Potenzial für den Einsatz.
Ich werde mir die anderen Artikel der Serie ansehen.
Vielen Dank an den Autor
 

Wenn ich die Maus bewege und das Rad über dem Panel scrolle, kann das Diagramm selbst manchmal scrollen.

Wie erhält man das erstellte Element eindeutig? Wenn wir schon vorher Elemente des Typs GRAPH_ELEMENT_TYPE_WF_TAB_CONTROL hatten, dann ist die Verwendung des Index 0 falsch.

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

Weiter... Wir haben die ID der Kopfzeile der Registerkarte von Interesse:

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

Fangen Sie das Änderungsereignis der aktiven Registerkarte ab, genauer gesagt, das Ereignis des Klickens auf die Kopfzeile. Wenn Sie auf die aktive Registerkarte klicken, wird das Ereignis weiterhin erzeugt.

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

Wie erhält man nun das Objekt des aktiven Feldes? Es ist ein CTabField, richtig?

Wie kann man das übergeordnete Objekt herausfinden?

 
Aliaksandr Hryshyn Ereignis weiterhin erzeugt.

Wie erhält man nun das Objekt des aktiven Feldes? Es ist ein CTabField, richtig?

Wie kann man das übergeordnete Objekt herausfinden?

1. Index 0 wird für das allererste an das Element angehängte Objekt verwendet. Index 1 steht für das zweite, Index 2 für das dritte und so weiter.

2. Sie können ein Feld aus der abgerufenen Kopfzeile über den gewünschten Index abrufen:

         //--- TabControl-Steuerelement erstellen
         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 Sie können das Tabulatorfeld aus dem TabControl-Objekt mit dem gewünschten Index abrufen:

         //--- TabControl-Steuerelement erstellen
         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. Ich verstehe die Fragenicht ganz. Wenn Sie herausfinden müssen, an welches Objekt das aktuelle gebunden ist, sollte es so funktionieren:

      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,"Panel-Beschreibung:",pnl.Description(),", Typ und Name: ",pnl.TypeElementDescription()," ",pnl.Name());
         //--- Padding auf 4 setzen
         pnl.SetPaddingAll(3);
         //--- Setzen Sie die Flags für Verschiebung, automatische Größenänderung und automatischen Größenänderungsmodus aus den Eingabeparametern
         pnl.SetMovable(InpMovable);
         pnl.SetAutoSize(InpAutoSize,false);
         pnl.SetAutoSizeMode((ENUM_CANV_ELEMENT_AUTO_SIZE_MODE)InpAutoSizeMode,false);
   
         //--- TabControl-Steuerelement erstellen
         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);  // Tabulatorfeld vom TabControl-Element abrufen tc
            CWinFormBase *base=tf.GetBase();       // Ermitteln des Basisobjekts für das Registerkartenfeld - muss TabControl sein tc
            CWinFormBase *main=tf.GetMain();       // Ermitteln Sie das Hauptobjekt für das Registerkartenfeld - muss CPanel pnl sein
           }

Wenn es die in den Kommentaren angegebenen Objekte nicht auf diese Weise zurückgibt, dann ist es ein Fehler und muss verfeinert werden