Einzelnen Beitrag anzeigen

Bodenseematze

Registriert seit: 10. Jul 2023
68 Beiträge
 
#1

TDBGrid/TJvDBGrid Highlighting direkt nach dem Einlesen

  Alt 8. Jul 2024, 10:14
Hallo,

ich verwende ein TJvDBGrid zur Darstellung von Detail-Datensätzen, wobei eine Spalte mit langem Bezeichnungstext in der Tabelle nie vollständig sichtbar ist und deshalb der Text der aktuell selektierten Zeile zusätzlich noch auf der Maske in einem TDBMemo dargestellt wird.
Das ganze basiert auf TDataSource / TQuery-Kombinationen (BDE - ja, ich weiß ) und Delphi 7.

Nachdem der Hauptdatensatz und die Detail-Datensätze eingelesen sind, wird auf den letzten Detaildatensatz positioniert.
Das Memo-Feld zeigt dann auch richtigerweise den vollständigen Text des letzten Satzes an.

Aber leider ist im Grid die (aktive) Zeile nicht markiert / hervorgehoben, sondern komischerweise in einer anderen Zeile eine Spalte gridselect-nok.jpg

Erst wenn ich in eine Zeile im Grid klicke, wird diese korrekt hervorgehoben:
gridselect-ok.jpg

BTW, das klicken ins Grid ohne eine Zeile zu "erwischen", verändert nichts - die Hervorhebung bleibt falsch.

Programmtechnisch habe ich auch schon versucht, den Fokus zu setzen - ohne Erfolg (vielleicht ist das auch nicht zum richtigen Zeitpunkt gemacht worden...)
(wurde im OnAfterScroll des Detail-Queries gemacht)

Das Grid hat MultiSelect und die folgenden Optionen gesetzt: dgEditing, dgTitles, dgColumnResize, dgColLines, dgRowLines, dgTabs, dgConfirmDelete, dgCancelOnExit, dgMultiSelect
Außerdem ist eine AlternateRowColor gesetzt, damit jede zweite Zeile anders hinterlegt ist.
AutoSizeRows ist gesetzt

Im OnDrawColumnCell-Handler des Grids werden:
- Spalten, deren Wert sich ggü. der Datenbank geändert hat, rot markiert
(bzw. alle Spalten einer Zeile, wenn die Zeile neu ist)
- wenn der TGridDrawState gdSelected enthält, wird die Font-Farbe auf clHighlightText gesetzt
(das ist standardmäßig nicht so und m.E. ein Bug)
- bei schreibgeschützten Spalten wird die Hintergrundfarbe "aufgehellt"
- die Spalten (bis auf die o.a. Bezeichnungsspalte) werden ggf. in der Breite angepasst, damit der Inhalt komplett sichtbar ist

Wie bekomme ich es hin, dass nach dem Einlesen der Datensätze die Zeile des aktiven Datensatzes hervorgehoben wird?
(die Option dgAlwaysShowSelection habe ich auch schon testweise gesetzt - hat nichts verändert)

Hier noch der relevante Code aus dem OnDrawColumnCell-Event des Grids:
Delphi-Quellcode:
procedure TMyClass.dbGridDetailDrawColumnCell(
                                    sender_ : TObject;
                                    const rect_ : TRect;
                                    iDataCol_ : Integer;
                                    col_ : TColumn;
                                    drawState_ : TGridDrawState );
var
   fld : TField;
   bHandled : Boolean;
   iWidthTitle : Integer;
   iWidth : Integer;
   fontContent : TFont;
   iRowCount : Integer;
   myGrid : THackedDBGrid;
begin
   if ( NOT Assigned(col_) ) then begin
      inherited;

      Exit;
   end;

   bHandled := false;
   fld := col_.Field;
   myGrid := THackedDBGrid( dbGridDetail );

   if ( NOT fld.Calculated ) then begin
      bHandled := true;
      if ( IsModified(fld) or
           (qryTail.CachedUpdates and ( qryTail.UpdateStatus() = usInserted )) ) then begin
         myGrid.Canvas.Font.Color := clRed;
      end
      else begin
         myGrid.Canvas.Font.Color := clWindowText;
      end;
   end;

   if ( (gdSelected in drawState_) ) then begin
      if ( myGrid.Canvas.Font.Color <> clHighlightText ) then begin
         bHandled := true;

         // die Fontfarbe "korrekt" setzen:
         myGrid.Canvas.Font.Color := clHighlightText;
      end;
   end
   else
   if ( col_.ReadOnly ) then begin
      // Hintergrundfarbe etwas "aufhellen":
      bHandled := true;
      if ( NOT Odd(myGrid.CurrentDrawRow) ) then begin
         myGrid.Canvas.Brush.Color
                           := Unit_HelperMisc.ColorLighterOrDarker(
                                    myGrid.AlternateRowColor,
                                    +10 );
      end
      else begin
         myGrid.Canvas.Brush.Color
                           := Unit_HelperMisc.ColorLighterOrDarker(
                                    myGrid.Color,
                                    +10 );
      end;
   end;

   // ggf. Größenanpassung (ausser bei der "Text"-Spalte, die wird am Schluss
   // dann in dbGridTailColsResize behandelt):
   if ( NOT _bGridTailColsWidthSet ) then begin
      if ( NOT AnsiSameText(col_.FieldName, 'Text') ) then begin
         iWidthTitle := 0;
         if ( dgTitles in myGrid.Options ) then begin
            // der Titel hat evtl. einen anderen Font
            // --> umstellen:
            fontContent := myGrid.Canvas.Font;
            myGrid.Canvas.Font := myGrid.TitleFont;
            iWidthTitle := myGrid.Canvas.TextExtent(
                                       col_.Title.Caption + ' \/' ).cx;
            myGrid.Canvas.Font := fontContent;
         end;
         iWidth := myGrid.Canvas.TextExtent(
                                       fld.DisplayText ).cx;
         if ( (myGrid.MinColumnWidth > 0) and
              (iWidth < myGrid.MinColumnWidth) ) then begin
            iWidth := myGrid.MinColumnWidth;
         end;

         if ( (myGrid.MaxColumnWidth > 0) and
              (iWidth > myGrid.MaxColumnWidth) ) then begin
            iWidth := myGrid.MaxColumnWidth;
         end;

         if ( iWidthTitle > iWidth ) then begin
            iWidth := iWidthTitle;
         end;
         Inc( iWidth, 5 );

         if ( iWidth <> col_.Width ) then begin
            col_.Width := iWidth;
         end;
      end; // if ( NOT AnsiSameText(col_.FieldName, 'Text') ) then

      // letzte Spalte
      // --> Breite der Text-Spalte auch setzen:
      if ( iDataCol_ = (myGrid.Columns.Count - 1) ) then begin
         dbGridTailSetColTextWidth();

         // letzte Zeile:
         if ( qryTailPos_Nr.AsInteger = _lstPosNr.Max ) then begin
            _bGridTailColsWidthSet := true;
         end;
      end;
   end; // if ( NOT _bGridTailColsWidthSet ) then

{$IFDEF notdef} // das hebt die falsche Zeile hervor:
   // aktuell ausgewählte Zeile auch entspr. markieren:
   if ( (myGrid.Row = ( myGrid.DataLink.ActiveRecord + 1 )) ) then begin
 //or
// (gdFocused in drawState_) or
// (gdSelected in drawState_) ) then begin
      myGrid.Canvas.Brush.Color := clHighLight;
      myGrid.Canvas.Font.Color := clHighLightText;
      bHandled := true;
   end;
{$ENDIF notdef}

   if ( bHandled ) then begin
      dbGridTail.DefaultDrawColumnCell( rect_, iDataCol_, col_, drawState_ );
   end;

   inherited;
end;

Geändert von Bodenseematze ( 8. Jul 2024 um 10:17 Uhr) Grund: Bilder hinzugefügt
  Mit Zitat antworten Zitat