StringGrid und Scrollprobleme



  • Hallo...

    Folgendes Problem. Habe ein Programm, in dem zwei Tabellen miteinander verglichen werden. Weicht die Spalte A eines Datensatzes der Tabelle A von dem mit Tabelle B ab, wird die Linie rot, weicht die Spalte B ab, wird die Linie gelb und wenn alles identlisch ist, dann wird die Zeile grau. Soweit so gut, funktioniert alles.

    Des weiteren habe ich eine Funktion, bei der, wenn in Tabelle A gescrollt wird, auch Tabelle B gescrollt wird.

    Den Code verwende ich wie hier: http://codezentrale.bplaced.net/dcz/?p=2142

    Arbeitet man mit den Auf-Ab-Pfeilen im Scrollbalken funktioniert auch das. Doch jetzt kommt der Haken: Scrollt man mit dem MouseWheel oder mit den Auf-Ab-Pfeil-Tasten (Tastatur) treten Schönheitsfehler auf:

    Ab und zu wechselt der Fokus der Tabelle den String Grid (also von SG1 auf SG2 oder umgekehrt). Dadurch springt dann die Position von SG1 unten auf SG2 oben und die nächsten Moves beim Scrollen haben kein Effekt, bis der Curser wider unten angekommen ist.

    Je nachdem wiviele farbige Zeilen dass existieren und wiviele Rows mit verschieden hohen Zeilen exisiteren, passiert das ganze sehr häufig. Ein wirkliches Muster ist jedoch nicht erkennbar.

    Folgende Lösungsansätze würde ich gerne probieren:

    1. nach dem Scrollereigniss den Focus auf die Tabelle setzen, die vorher aktiv war. Das Problem dabei:

    StringGrid2TopLeftChanged(TObject *Sender)
    

    ändert auch bei der Tabelle, die nur auf das Scrollereigniss reagiert. So wie im Beispiel von codezentrale wird beim scrollen in SG1 zuerst

    void __fastcall TForm1::StringGrid1TopLeftChanged(TObject *Sender)
    

    aufgerufen, danach

    void __fastcall TForm1::StringGrid2TopLeftChanged(TObject *Sender)
    

    . Jedoch nur im Normalfall. Bei unterschiedlichen Tabellen kann es sein, dass dann SG2 gar keine Veränderung der Eigenschaft TopLeftChanged machen muss und daher der Fokus nicht mehr zurückgesetzt wird auf SG1. Besser währe hier nur auf das Scrollereigniss zu reagieren(anstatt auf TopLeftChanged). Doch ich finde keine Eigenschaft OnScrollDown oder so...

    2. kann man den Fokus ganz von einer Tabelle wegnehmen? Vielleicht kann er dann auch nicht mehr am falschen Ort hängen bleiben.

    Vielleicht gehts ja auch ganz anders... Für Ideen danke ich im Voraus!

    void __fastcall TForm1::StringGrid1TopLeftChanged(TObject *Sender)
    {
    if(Form1->Scroll_On_Both->Checked){
       // vertikale ScrollBarposition von StringGrid1 ermitteln
       int iScrollPosV = GetScrollPos(StringGrid1->Handle, SB_VERT);
    
       // vertikale ScrollBarposition von StringGrid2 setzen
       SetScrollPos(StringGrid2->Handle, SB_VERT, iScrollPosV, true);
    
       // Anzeige des Inhalts von StringGrid2 an die akt. ScrollBarposition anpassen
       StringGrid2->Perform(WM_VSCROLL, MAKEWPARAM(SB_THUMBPOSITION, iScrollPosV), 0);
    
    //   StringGrid1->Selection.Top=iScrollPosV;
       }
    
    }
    //---------------------------------------------------------------------------
    
    void __fastcall TForm1::StringGrid2TopLeftChanged(TObject *Sender)
    {
    
    if(Form1->Scroll_On_Both->Checked){
       // vertikale ScrollBarposition von StringGrid1 ermitteln
       int iScrollPosV = GetScrollPos(StringGrid2->Handle, SB_VERT);
    
       // vertikale ScrollBarposition von StringGrid2 setzen
       SetScrollPos(StringGrid1->Handle, SB_VERT, iScrollPosV, true);
    
       // Anzeige des Inhalts von StringGrid2 an die akt. ScrollBarposition anpassen
       StringGrid1->Perform(WM_VSCROLL, MAKEWPARAM(SB_THUMBPOSITION, iScrollPosV), 0);
    
    //   StringGrid2->Selection.Top=iScrollPosV;
       }
    
    }
    
    void __fastcall TForm1::StringGrid2DrawCell(TObject *Sender, int ACol,
          int ARow, TRect &Rect, TGridDrawState State)
    {  int RowHt, BiggestColWidth;
    // Titelzeile: Nicht farbig bemahlen
    if(ARow!=0){
       // Nur wenn der Vektor geladen ist, darf direkt darauf zugegriffen werden, ansonsten Acces Violation
       if(StringGrid2IsFilled==true){
          if(ArtStueli2[ARow-1].OnlyOnThisStueli==true){
             if(Form1->PaintDifferentArtRed->Checked==true){
                Form1->StringGrid2->Canvas->Brush->Color = clRed;
                StringGrid2->Canvas->Font->Color = clBlack;
                StringGrid2->Canvas->FillRect(Rect);
                }
             else{
                //ohne das Redrawing entstehen Pixelfehler
                Form1->StringGrid2->Canvas->Brush->Color = clWhite;
                StringGrid2->Canvas->Font->Color = clBlack;
                StringGrid2->Canvas->FillRect(Rect);
                }
             }
             else if(ArtStueli2[ARow-1].DiffDesig==true){
             if(Form1->PaintDifferentDesigYellow->Checked==true){
                Form1->StringGrid2->Canvas->Brush->Color = clYellow;
                StringGrid2->Canvas->Font->Color = clBlack;
                StringGrid2->Canvas->FillRect(Rect);
                }
                else{
                //ohne das Redrawing entstehen Pixelfehler
                Form1->StringGrid2->Canvas->Brush->Color = clWhite;
                StringGrid2->Canvas->Font->Color = clBlack;
                StringGrid2->Canvas->FillRect(Rect);
                }
             }
             else{
             if(Form1->PaintSameGrey->Checked==true){
                Form1->StringGrid2->Canvas->Brush->Color=clBtnFace;
                StringGrid2->Canvas->Font->Color = clBlack;
                StringGrid2->Canvas->FillRect(Rect);
                }
                else{
                //ohne das Redrawing entstehen Pixelfehler
                Form1->StringGrid2->Canvas->Brush->Color = clWhite;
                StringGrid2->Canvas->Font->Color = clBlack;
                StringGrid2->Canvas->FillRect(Rect);
                }
             }
    
          RowHt=DrawText(StringGrid2->Canvas->Handle, StringGrid2->Cells[ACol][ARow].c_str(), -1, &Rect, DT_WORDBREAK | DT_VCENTER | DT_LEFT | DT_CALCRECT );
          if ((RowHt + 3) > StringGrid2->DefaultRowHeight){
             StringGrid2->RowHeights[ARow] = RowHt + 3;
             }
    
          DrawText(StringGrid2->Canvas->Handle, StringGrid2->Cells[ACol][ARow].c_str(), -1, &Rect, DT_WORDBREAK | DT_VCENTER | DT_LEFT );   //  | DT_NOCLIP
          }
       }
       else{
       //Head Row
       Form1->StringGrid2->Canvas->Brush->Color = clBtnFace;
       StringGrid2->Canvas->Font->Color = clBlack;
       StringGrid2->Canvas->FillRect(Rect);
       DrawText(StringGrid2->Canvas->Handle, StringGrid2->Cells[ACol][ARow].c_str(), -1, &Rect, DT_WORDBREAK | DT_VCENTER | DT_LEFT ); // | DT_NOCLIP
       }
       //bugbehebungsversuch für scrolling fehler. problem: jedes mal bei focused() giebt es einen redraw.
    /*if(FocusedGrid==1){
       Form1->StringGrid1->Focused();
       }
       else if(FocusedGrid==2){
       Form1->StringGrid2->SetFocus();
       }*/
    }
    


  • Habe mittlerweile die Lösung gefunden. Am Ende wars ganz einfach... Das Problem wird behoben, in dem nicht die Position des Scrollbalkens verändert wird, sondern die Eigenschaft TopRow. Die Darstellung ist danach zwar minim anders, (Bei unterschiedlich hohen Rows wird jetzt nicht mehr gleich viele % gescrollt, sondern in beiden Tabellen einfach bis zum nächsten Row) jedoch ist das für meinen Fall nicht wirklich störend, eher etwas besser.

    void __fastcall TForm1::StringGrid1TopLeftChanged(TObject *Sender)
    {
    if(Form1->Scroll_On_Both->Checked){
       if(Form1->StringGrid2->RowCount>Form1->StringGrid1->TopRow){
          Form1->StringGrid2->TopRow=Form1->StringGrid1->TopRow;
          }
       }
    
    }
    //---------------------------------------------------------------------------
    
    void __fastcall TForm1::StringGrid2TopLeftChanged(TObject *Sender)
    {
    
    if(Form1->Scroll_On_Both->Checked){
       if(Form1->StringGrid1->RowCount>Form1->StringGrid2->TopRow){
          Form1->StringGrid1->TopRow=Form1->StringGrid2->TopRow;
          }
       }
    
    }
    

    Soweit ich das nachvolziehen kann, treten die Scroll-Probleme mit der Routine von Codezetrale dann auf, wenn Tabellen mit unterschiedlich hohen Zeilen gescrollt werden.


Anmelden zum Antworten