Entwickler-Ecke
Grafische Benutzeroberflächen (VCL & FireMonkey) - StringGrid und Bilder
sigi - Sa 25.02.12 11:42
Titel: StringGrid und Bilder
Hallo,
ich will, das bei einem Klick auf eine bestimmte Zelle ein Bild angezeigt wird, mit
Delphi-Quelltext
1:
| SGrid.Canvas.StretchDraw(XRect, arrBilder[0].Picture.Graphic); |
klappt das auch mit der ersten Zelle, wenn aber die nächste angeklickt wird, verschwindet das erste Bild, wie kann ich das verhindern?
Gruß sigi
Moderiert von
Narses: Delphi-Tags hinzugefügt
jaenicke - Sa 25.02.12 12:03
Du musst in OnDrawCell zeichnen, sonst ist beim Neuzeichnen des Grids (z.B. wenn sich etwas ändert, durch einen Klick oder durch ein anderes Fenster darüber) alles weg. Denn wenn du nicht darauf reagierst, dass dir das Grid sagt, dass eine Zelle neu gezeichnet werden muss (OnDrawCell), wird es auch nicht wieder gezeichnet nachdem das Standardgrid gezeichnet ist.
Wenn du also in OnClick nur einmalig zeichnest, weißt du nicht wie lange das wirklich sichtbar ist.
sigi - Sa 25.02.12 16:42
Hallo Sebastian,
es steht im OnDrawCell, oder habe ich das verkehrt verstanden?
Delphi-Quelltext
1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15:
| procedure TForm1.SGridDrawCell(Sender: TObject; ACol, ARow: Integer; Rect: TRect; State: TGridDrawState); begin SGrid.Canvas.StretchDraw(XRect, arrBilder[0].Picture.Graphic); end;
procedure TForm1.SGridSelectCell(Sender: TObject; ACol, ARow: Integer; var CanSelect: Boolean); begin XRect.Left := ACol * 121;
XRect.Top := ARow * 91; XRect.Right := XRect.Left + 121; XRect.Bottom := XRect.Top + 91; end; |
Gruß sigi
Moderiert von
Martok: Delphi-Tags hinzugefügt
jaenicke - Sa 25.02.12 16:56
Ja, dann ist das im richtigen Event. Das hattest du ja nicht mitgepostet. Der Fehler liegt woanders wie nun zu sehen ist:
In OnDrawCell zeichnest du das Bild an genau eine einzige Stelle. Nämlich die, die in XRect steht. Nun überlege einmal was passiert, wenn du die nächste Zelle anklickst. XRect wird auf die neue Zelle gesetzt. Nun wird daher nur noch an dieser Stelle gezeichnet. Du zeichnest nun einmal nur an einer Stelle.
Ich glaube du hast OnDrawCell noch nicht wirklich verstanden...
Schau dir einmal dessen Parameter an. Du bekommst da das Rechteck direkt übergeben. Das brauchst du also nicht selbst zu berechnen. Das Event wird für jede Zelle im Grid aufgerufen. Welche du gerade neu zeichnen musst, steht in den Parametern ACol und ARow.
Was musst du also machen? Nur speichern welche Zellen angeklickt wurden. Zum Beispiel in einem zweidimensionalen Array oder einer anderen Datenstruktur, je nach Anwendungszweck. Wenn dann OnDrawCell ausgelöst wird, schaust du in dem Array nach, ob an der Stelle ein Bild gezeichnet werden soll.
Wenn du manuell ein Neuzeichnen auslösen möchtest, weil sich die Daten geändert haben, kannst du Invalidate des Stringgrids aufrufen.
sigi - So 26.02.12 15:41
jaenicke hat folgendes geschrieben : |
Ich glaube du hast OnDrawCell noch nicht wirklich verstanden...
|
Da muss ich dir recht geben, aber was nicht ist, kann noch werden, danke erstmal.
Gruß sigi
jaenicke - So 26.02.12 16:06
Schreib einfach einmal in einem neuen Projekt mit nur einem TStringGrid und einem TMemo diesen Code in OnDrawCell:
Delphi-Quelltext
1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14:
| var GridCanvas: TCanvas; begin GridCanvas := (Sender as TStringGrid).Canvas; GridCanvas.Brush.Color := $404040 + Random($88) + Random($88) shl 8 + Random($88) shl 16; GridCanvas.Brush.Style := bsSolid; GridCanvas.FillRect(Rect); GridCanvas.Brush.Style := bsClear; GridCanvas.TextOut(Rect.Left, Rect.Top, FormatDateTime('hh:mm:ss', Now)); Memo1.Lines.Add(Format('Zeichne Zelle bei (%d, %d) an Position (%d, %d, %d, %d)', [ACol, ARow, Rect.Left, Rect.Top, Rect.Right, Rect.Bottom])); |
Vielleicht wird dann klarer was passiert. Die Farbberechnung ist nur ein Beispiel zur besseren Visualisierung, das ist erst einmal egal, wenn du das nicht verstehst.
Wenn du nun mit der Maus auf Zellen klickst, dann siehst du, dass durchaus mehrere neu gezeichnet werden, aber nicht alle. Das heißt wann genau das Neuzeichnen einer Zelle passiert, weißt du nicht. In OnDrawCell darfst du aber immer nur die aktuelle Zelle an der per Parameter übergebenen Position zeichnen, mehr nicht.
Du kannst auch testweise mit einem Button mit Invalidate das Neuzeichnen aller Zellen auslösen.
Entwickler-Ecke.de based on phpBB
Copyright 2002 - 2011 by Tino Teuber, Copyright 2011 - 2026 by Christian Stelzmann Alle Rechte vorbehalten.
Alle Beiträge stammen von dritten Personen und dürfen geltendes Recht nicht verletzen.
Entwickler-Ecke und die zugehörigen Webseiten distanzieren sich ausdrücklich von Fremdinhalten jeglicher Art!