2012-10-23 12 views
6

Mit Delphi 2010 und einer TStringGrid-Komponente werden derzeit fünf Bilder aus einer Datenbankabfrage angezeigt. HierHinzufügen einer grafischen Leiste zu einem StringGrid-Zeichen

ist ein vereinfachter Beispiel dafür, was ich tue

// eingerichtet, um die Gitter

procedure TGriddata.FormCreate(Sender: TObject); 
begin 
grdMain.Rows[0].commatext:='"One","Two","Three","Four","Five"'; 
grdMain.ColWidths[0]:= 50; 
grdMain.ColWidths[1]:= 175; 
grdMain.ColWidths[2]:= 175; 
grdMain.ColWidths[3]:= 100; 
grdMain.ColWidths[4]:= 300; 
end; 

// zeigen die Daten im Raster // Note, Ich zeige nicht meine Schöpfung , Ausführung, oder die Abfrage zerstören

procedure TGriddata.load; 
begin 
... 
grdMain.Cells[0,row]:= FieldByName('one').AsString; 
grdMain.Cells[1,row]:= FieldByName('two').AsString; 
grdMain.Cells[2,row]:= FieldByName('three').AsString; 
grdMain.Cells[3,row]:= FieldByName('four').AsString; 
//draw progress bar here 
... 
end; 

eine der Säulen („Five“) einen dunkelblauen horizontalen Balken in der Spalte angezeigt werden muss. Es sollte auch etwas Text zentriert in der Leiste angezeigt werden. Ich habe keine Erfahrung mit der benutzerdefinierten Zeichnung. Welche Eigenschaften setze ich, um nur die eine Spalte benutzerdefiniert zu zeichnen und die Standardzeichnung für die anderen Spalten zu verwenden?

+0

Siehe [diesen Kommentar] (http://stackoverflow.com/questions/7044125/delphi-draw-own-progress-bar-in-list-view/7048062#comment8445655_7048062) von Ian Boyd! – NGLN

Antwort

9

Fügen Sie den Zellen den Text hinzu, wie Sie es normalerweise tun würden. Aber Sie müssen diese Balken im OnDrawCell Ereignis zeichnen. Lassen Sie DefaultDrawing wie (True Standardeinstellung), und löschen Sie die bereits gezogenen Zelle Text in diesen Spalten, indem sie es im Voraus ausfüllen:

procedure TForm1.grdMainDrawCell(Sender: TObject; ACol, ARow: Integer; 
    Rect: TRect; State: TGridDrawState); 
var 
    Progress: Single; 
    R: TRect; 
    Txt: String; 
begin 
    with TStringGrid(Sender) do 
    if (ACol = 4) and (ARow >= FixedRows) then 
    begin 
     Progress := StrToFloatDef(Cells[ACol, ARow], 0)/100; 
     Canvas.FillRect(Rect); 
     R := Rect; 
     R.Right := R.Left + Trunc((R.Right - R.Left) * Progress); 
     Canvas.Brush.Color := clNavy; 
     Canvas.Rectangle(R); 
     Txt := Cells[ACol, ARow] + '%'; 
     Canvas.Brush.Style := bsClear; 
     IntersectClipRect(Canvas.Handle, R.Left, R.Top, R.Right, R.Bottom); 
     Canvas.Font.Color := clHighlightText; 
     DrawText(Canvas.Handle, PChar(Txt), -1, Rect, DT_SINGLELINE or 
     DT_CENTER or DT_VCENTER or DT_END_ELLIPSIS or DT_NOPREFIX); 
     SelectClipRgn(Canvas.Handle, 0); 
     ExcludeClipRect(Canvas.Handle, R.Left, R.Top, R.Right, R.Bottom); 
     Canvas.Font.Color := clWindowText; 
     DrawText(Canvas.Handle, PChar(Txt), -1, Rect, DT_SINGLELINE or 
     DT_CENTER or DT_VCENTER or DT_END_ELLIPSIS or DT_NOPREFIX); 
     SelectClipRgn(Canvas.Handle, 0); 
    end; 
end; 

Custom drawn bars in StringGrid

Weitere Optionen könnten Sie this DrawStatus routine betrachten.

4

Hier können Sie ein Beispiel anzeigen (Draw percentage in a cell in a Grid), um eine Leiste in einer Zelle eines TStringGrid zu zeichnen. Die Erklärung ist in Spanisch, aber Sie können den Code herunterladen, das ist sehr einfach. Sie können auch die automatische Übersetzung rechts auf der Seite verwenden.

enter image description here

procedure TFormDrawCell.DBGrid1DrawColumnCell(Sender: TObject; 
    const Rect: TRect; DataCol: Integer; Column: TColumn; 
    State: TGridDrawState); 
const 
    STR_EMPTY = ''; 
    CHAR_PERCENT = '%'; 
    SPACE_TO_CENTER_CELLTEXT = 0; 
var 
    fValue: Integer; 
    ActualPenColor, ActualBrushColor: TColor; 
    EmptyDS: Boolean; 
    DrawRect: TRect; 
    fWidth1, fLeft2: Integer; 
    StrValue: string; 
begin 
    if not (Column.FieldName = 'Precent') then 
    Exit; 

    if not (cbdraw.Checked) then 
    Exit; 

    EmptyDS := ((TDBGrid(Sender).DataSource.DataSet.EoF) and 
       (TDBGrid(Sender).DataSource.DataSet.Bof)); 

    if (Column.Field.IsNull) then begin 
    fValue := -1; 
    StrValue := STR_EMPTY; 
    end 
    else begin 
    fValue := Column.Field.AsInteger; 
    StrValue := IntToStr(fValue) + CHAR_PERCENT; 
    end; 

    DrawRect := Rect; 
    InflateRect(DrawRect, -1, -1); 

    fWidth1 := (((DrawRect.Right - DrawRect.Left) * fValue) DIV 100); 

    ActualPenColor := TDBGrid(Sender).Canvas.Pen.Color; 
    ActualBrushColor := TDBGrid(Sender).Canvas.Brush.Color; 
    TDBGrid(Sender).Canvas.Pen.Color := clHighlight; 
    TDBGrid(Sender).Canvas.Brush.Color := clWhite; 
    TDBGrid(Sender).Canvas.Rectangle(DrawRect); 

    if (fValue > 0) then begin 
    TDBGrid(Sender).Canvas.Pen.Color := clSkyBlue; 
    TDBGrid(Sender).Canvas.Brush.Color := clSkyBlue; 
    DrawRect.Right := DrawRect.Left + fWidth1; 
    InflateRect(DrawRect, -1, -1); 
    TDBGrid(Sender).Canvas.Rectangle(DrawRect); 
    end; 

    if not (EmptyDS) then begin 
    DrawRect := Rect; 
    InflateRect(DrawRect, -2, -2); 
    TDBGrid(Sender).Canvas.Brush.Style := bsClear; 
    fLeft2 := DrawRect.Left + (DrawRect.Right - DrawRect.Left) shr 1 - 
       (TDBGrid(Sender).Canvas.TextWidth(StrValue) shr 1); 
    TDBGrid(Sender).Canvas.TextRect(DrawRect, fLeft2, 
            DrawRect.Top + SPACE_TO_CENTER_CELLTEXT, StrValue); 
    end; 

    TDBGrid(Sender).Canvas.Pen.Color := ActualPenColor; 
    TDBGrid(Sender).Canvas.Brush.Color := ActualBrushColor; 
end; 

Grüße.

+5

Bitte bearbeiten Sie Ihre Antwort und fügen Sie den Code hier hinzu, anstatt nur auf einen externen Standort zu verlinken. Wenn die externe Website aus irgendeinem Grund nicht verfügbar ist, wird Ihre Antwort bedeutungslos. Es ist auch nicht für zukünftige Leser der Website suchbar. Vielen Dank. –

+0

@KenWhite: Ich habe mir die Freiheit genommen, den relevanten Teil des Codes hier zu veröffentlichen, und habe einige leichte Vereinfachungen vorgenommen, um es lesbarer zu machen. –

+0

Danke für den Code hier einfügen, @ Wouter van Nifterick. –