Autor Beitrag
sigi
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 18

Win7 Pro 64bit
Delphi XE5 Prof
BeitragVerfasst: Sa 25.02.12 11:42 
Hallo,

ich will, das bei einem Klick auf eine bestimmte Zelle ein Bild angezeigt wird, mit
ausblenden 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 user profile iconNarses: Delphi-Tags hinzugefügt
jaenicke
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 19340
Erhaltene Danke: 1752

W11 x64 (Chrome, Edge)
Delphi 12 Pro, C# (VS 2022), JS/HTML, Java (NB), PHP, Lazarus
BeitragVerfasst: 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 Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 18

Win7 Pro 64bit
Delphi XE5 Prof
BeitragVerfasst: Sa 25.02.12 16:42 
Hallo Sebastian,

es steht im OnDrawCell, oder habe ich das verkehrt verstanden?

ausblenden 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 user profile iconMartok: Delphi-Tags hinzugefügt
jaenicke
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 19340
Erhaltene Danke: 1752

W11 x64 (Chrome, Edge)
Delphi 12 Pro, C# (VS 2022), JS/HTML, Java (NB), PHP, Lazarus
BeitragVerfasst: 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 Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 18

Win7 Pro 64bit
Delphi XE5 Prof
BeitragVerfasst: So 26.02.12 15:41 
user profile iconjaenicke hat folgendes geschrieben Zum zitierten Posting springen:

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
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 19340
Erhaltene Danke: 1752

W11 x64 (Chrome, Edge)
Delphi 12 Pro, C# (VS 2022), JS/HTML, Java (NB), PHP, Lazarus
BeitragVerfasst: So 26.02.12 16:06 
Schreib einfach einmal in einem neuen Projekt mit nur einem TStringGrid und einem TMemo diesen Code in OnDrawCell:
ausblenden 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;
  // Ganzer Zelle einen farbigen Hintergrund geben:
  GridCanvas.Brush.Color := $404040 + Random($88) + Random($88shl 8 + Random($88shl 16;
  GridCanvas.Brush.Style := bsSolid;
  GridCanvas.FillRect(Rect);
  // Aktuelle Uhrzeit draufschreiben:
  GridCanvas.Brush.Style := bsClear;
  GridCanvas.TextOut(Rect.Left, Rect.Top, FormatDateTime('hh:mm:ss', Now));
  // Status ausgeben, dass gezeichnet wurde:
  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.