Frage zu StringGrid

Rund um die LCL und andere Komponenten
Benutzeravatar
juelin
Beiträge: 237
Registriert: Sa 24. Jul 2021, 18:03
OS, Lazarus, FPC: Linux Ubuntu 22. Windows 10 Delphi 11.3 (L 0.9.xy FPC 2.2.z)
CPU-Target: 64Bit
Wohnort: Mannheim

Frage zu StringGrid

Beitrag von juelin »

Hallo,
ich habe im Programm ein StringGrid und möchte wissen, welcher Eintrag der User im StringGrid anklickt.
Das mache ich über das Ereignis TForm1.StringGrid1SelectCell.
Nun zu meinem Problem:
Wenn der User einen Eintrag anklickt kommt das Programm natürlich in die Routine TForm1.StringGrid1SelectCell.
Soweit so gut.
Allerdings kommt das Programm auch in die Routine wenn der User irgendwo im StringGrid klick (wo gar kein Eintrag ist).
Die Software tut dann so als hätte er den erstern Eintrag (habe nur einen Eintrag) angeklickt.
Das ist nicht ideal.
Hat da jemand Erfahrung?
Danke und Gruß
Jürgen

PS: Er kommr auch in die Routine TForm1.StringGrid1SelectCell wenn ich nur mit der Maus über das StringGrid gehen (so wie als OnMouseMove).
Aber erst wenn ich mindestens 1 mal im StringGrid geklickt habe.

wp_xyz
Beiträge: 5129
Registriert: Fr 8. Apr 2011, 09:01

Re: Frage zu StringGrid

Beitrag von wp_xyz »

Dateianhänge
allow_outbound_events.zip
(1.99 KiB) 130-mal heruntergeladen
Zuletzt geändert von wp_xyz am Mi 11. Dez 2024, 10:27, insgesamt 1-mal geändert.

Benutzeravatar
h-elsner
Lazarusforum e. V.
Beiträge: 281
Registriert: Di 24. Jul 2012, 15:42
OS, Lazarus, FPC: LINUX Mint21.1, Win10, Lazarus 2.2.4, FPC3.2.2
CPU-Target: X86-64; arm 32bit
Wohnort: Illertissen
Kontaktdaten:

Re: Frage zu StringGrid

Beitrag von h-elsner »

Ich verstehe die Frage nicht ganz. Bei mir funktioniert es. Dass leere Zellen auch ausgewertet werden können, ist meiner Meinung nach Pflicht. Die Ereignisroutine wäre sonst unlogisch und leere Zellen können gar nicht behandelt werden, was echt blöd wäre.
Man kann aber mit StringGrid1.Cells[aCol, aRow].IsEmpty feststellen, ob die Zelle leer ist.
Die Maus drüber zu ziehen tut bei mir nichts (also was du mit PS gesagt hast). Vielleicht ist bei den Optionen da etwas gesetzt, was dieses Verhalten erzeugt. Ich habe da nicht alles durchprobiert. Wenn du bei den Optionen etwas gegenüber der Defaultwerte geändert hast, siehst du es ja, wenn das Item rot markiert ist.

Benutzeravatar
theo
Beiträge: 10856
Registriert: Mo 11. Sep 2006, 19:01

Re: Frage zu StringGrid

Beitrag von theo »

wp_xyz hat geschrieben: Mi 11. Dez 2024, 01:19 https://wiki.lazarus.freepascal.org/Gri ... oundEvents
Ja, das ist es wohl.
Ich muss zugeben, dass ich das auf die Schnelle auch nicht gefunden hätte.
Warum ist das nicht "published" und taucht somit nicht im Objektinspektor auf, sei es auch nur als "Option"?
Von mir aus könnte dies gerne das Standardverhalten sein. Die "OutboundEvents" sind ja doch eher unerwartet.

Benutzeravatar
juelin
Beiträge: 237
Registriert: Sa 24. Jul 2021, 18:03
OS, Lazarus, FPC: Linux Ubuntu 22. Windows 10 Delphi 11.3 (L 0.9.xy FPC 2.2.z)
CPU-Target: 64Bit
Wohnort: Mannheim

Re: Frage zu StringGrid

Beitrag von juelin »

Hallo zusammen,
Danke für Eure Info.
Habe das mit dem Outbound ausprobiert.
StringGrid1.AllowOutboundEvents:=False;
Leider ist es so: solange ich noch kein Eintrag im StringGrid angeklickt habe passiert auch nichts, wenn ich mit der Maus
irgendwo in das StringGrid gehe.
Sobald ich aber einmal einen Eintrag im StringGrid angeklickt habe
so geht er in die Routine OnSelectCell sobald ich nur mit der Maus irgendwo in das StringGrid gehe (brache nicht mal klicken).
Der Befehl: StringGrid1.AllowOutboundEvents:=False; ist dabei in OnFormActivate drin.
Das verstehe ich nicht.
Versteht Ihr das?
Danke und Gruß
Jürgen

Benutzeravatar
Zvoni
Beiträge: 363
Registriert: Fr 5. Jul 2024, 08:26
OS, Lazarus, FPC: Windoof 10 Pro (Laz 2.2.2 FPC 3.2.2)
CPU-Target: 32Bit
Wohnort: BW

Re: Frage zu StringGrid

Beitrag von Zvoni »

Ist dem MouseEnter, MouseMove-Ereignis usw. vielleicht die OnSelectCell-Prozedur zugeordnet?
Ein System sie alle zu knechten, ein Code sie alle zu finden,
Eine IDE sie ins Dunkel zu treiben, und an das Framework ewig zu binden,
Im Lande Redmond, wo die Windows drohn.

wp_xyz
Beiträge: 5129
Registriert: Fr 8. Apr 2011, 09:01

Re: Frage zu StringGrid

Beitrag von wp_xyz »

juelin hat geschrieben: Mi 11. Dez 2024, 15:44 Leider ist es so: solange ich noch kein Eintrag im StringGrid angeklickt habe passiert auch nichts, wenn ich mit der Maus
irgendwo in das StringGrid gehe.
Was heißt "gehe" hier? Einfach die Maus ins Grid reinbewegen, oder irgendwo im Grid klicken?

Benutzeravatar
juelin
Beiträge: 237
Registriert: Sa 24. Jul 2021, 18:03
OS, Lazarus, FPC: Linux Ubuntu 22. Windows 10 Delphi 11.3 (L 0.9.xy FPC 2.2.z)
CPU-Target: 64Bit
Wohnort: Mannheim

Re: Frage zu StringGrid

Beitrag von juelin »

Es sind die Ereignisse onMouseMove, MouseEnter usw sind NICHT belegt (im Obejkt inspektor keine Routine zu geordnet).

wp_xyz : So wie Du geschrieben hast. den Mousezeigen in das StringGrid bewegen.

Gruß
Jürgen

Benutzeravatar
juelin
Beiträge: 237
Registriert: Sa 24. Jul 2021, 18:03
OS, Lazarus, FPC: Linux Ubuntu 22. Windows 10 Delphi 11.3 (L 0.9.xy FPC 2.2.z)
CPU-Target: 64Bit
Wohnort: Mannheim

Re: Frage zu StringGrid

Beitrag von juelin »

Damit Ihr nicht immer nachfragen müsst
hier meine Daten.

Code: Alles auswählen

procedure TForm1.StringGrid1SelectCell(Sender: TObject; aCol, aRow: Integer;
  var CanSelect: Boolean);
  var h1: string;
  var h2: integer;
  var h3: integer;
begin
  CanSelect:=False;
  egrid:=aCol;
  egrid:=aRow;
  if Gridart = 1 then
  begin
    if egrid > 0 then
    begin
      h1:=StringGrid1.Cells[0, egrid];
      egrid:=0;
      h2:=Length(h1);
      if h2 > 0 then
      begin
        JaNein:=messagedlg('Projekt '+h1+' laden?', mtConfirmation, [mbYes, mbNo], 0);
        if (JaNein = mrYes) then
        begin
          Projektname:=h1;
          Routinename:='';
          Routinefenster:='';
          Routineprogramm:='';
          Raster:=False;
          Diagramm:=False;
          Zoomfaktor:=1;
          BildausschnittX:=1;
          BildausschnittY:=1;
          MenueSet;
          ImageLoe;
          MenuItem20.Caption:='Raster an';
          Raster:=False;
          ImageRasteraus;
          Kopfzeile;
          Ausschnittrechnung;
          h2:=0;
          ZQuery1.SQL.Text:='SELECT * FROM routinen WHERE Projekt=:pro AND Name=:nam';
          ZQuery1.ParamByName('pro').asString:=Projektname;
          ZQuery1.ParamByName('nam').asString:=Projektname;
          ZQuery1.Open;
          while not ZQuery1.EOF do
          begin
            h2:=1;
            Routinefenster:=ZQuery1.Fields[3].AsString;
            Routineprogramm:=ZQuery1.Fields[4].AsString;
            Bildheight:=ZQuery1.Fields[5].AsInteger;
            Bildwidth:=ZQuery1.Fields[6].AsInteger;
            ZQuery1.Next;
          end;
          ZQuery1.Close;
          if h2 = 1 then
          begin
            Routinename:=Projektname;
            MenueSet;
            Kopfzeile;
            Ausschnittrechnung;
            Gridladen(2);
            h2:=0;
            ZQuery1.SQL.Text:='SELECT * FROM elemente WHERE Projekt=:pro AND Routine=:nam';
            ZQuery1.ParamByName('pro').asString:=Projektname;
            ZQuery1.ParamByName('nam').asString:=Projektname;
            ZQuery1.Open;
            while not ZQuery1.EOF do
            begin
              h3:=ZQuery1.Fields[3].AsInteger;
              if h3 > 0 then h2:=1;
              ZQuery1.Next;
            end;
            ZQuery1.Close;
            if h2 = 1 then
            begin
              Diagramm:=True;
              Flussdiagramm;
              Kopfzeile;
              MenueSet;
              Ausschnittrechnung;
              ImageLoe;
              Image1.Canvas.CopyRect(Rect(0,0,Image1.Width-1,Image1.Height-1), Image2.Canvas, Rect(AusXPos,AusYPos,AnzPixX+AusXPos,AnzPixY+AusYPos));
              Diagramm:=False;
              Form1.ScrollBar1.Min:=1;
              Form1.ScrollBar1.Max:=1;
              Form1.ScrollBar1.Position:=1;
              Form1.ScrollBar2.Min:=1;
              Form1.ScrollBar2.Max:=1;
              Form1.ScrollBar2.Position:=1;
              Form1.ScrollBar3.Min:=1;
              Form1.ScrollBar3.Max:=5;
              Form1.ScrollBar3.Position:=1;
              Form1.ScrollBar1.Visible:=True;
              Form1.ScrollBar2.Visible:=True;
              Form1.ScrollBar3.Visible:=True;
              Form1.ScrollBar1.Max:=Ceil(Orgwidth / AnzPixX);
              Form1.ScrollBar2.Max:=Ceil(Orgheight / AnzPixY);
              Diagramm:=True;
            end;
          end;
          CanSelect:=True;
        end;
      end;
    end;
  end;
  if Gridart = 2 then
  begin
    if egrid > 0 then
    begin
      h1:=StringGrid1.Cells[0, egrid];
      egrid:=0;
      h2:=Length(h1);
      if h2 > 0 then
      begin
        JaNein:=messagedlg('Routine '+h1+' laden?', mtConfirmation, [mbYes, mbNo], 0);
        if (JaNein = mrYes) then
        begin
          Routinename:=h1;
          Routinefenster:='';
          Routineprogramm:='';
          ZQuery1.SQL.Text:='SELECT * FROM routinen WHERE Projekt=:pro AND Name=:nam';
          ZQuery1.ParamByName('pro').asString:=Projektname;
          ZQuery1.ParamByName('nam').asString:=Routinename;
          ZQuery1.Open;
          while not ZQuery1.EOF do
          begin
            Routinefenster:=ZQuery1.Fields[3].AsString;
            Routineprogramm:=ZQuery1.Fields[4].AsString;
            Bildheight:=ZQuery1.Fields[5].AsInteger;
            Bildwidth:=ZQuery1.Fields[6].AsInteger;
            ZQuery1.Next;
          end;
          ZQuery1.Close;
          Raster:=False;
          Diagramm:=False;
          Zoomfaktor:=1;
          BildausschnittX:=1;
          BildausschnittY:=1;
          MenueSet;
          ImageLoe;
          MenuItem20.Caption:='Raster an';
          Raster:=False;
          ImageRasteraus;
          Kopfzeile;
          Ausschnittrechnung;
          CanSelect:=True;
        end;
      end;
    end;
  end;
  egrid:=0;
end;
Die Eigenschaften von StringGrid in bild1 bis bild4
Die Ereignisse von StringGrid in bild5 bis bild8

Ich hoffe jetzt könnt ihr was finden.

Gruß
Jürgen
Dateianhänge
bild3.jpg
bild3.jpg (49.39 KiB) 3462 mal betrachtet
bild2.jpg
bild2.jpg (50.97 KiB) 3462 mal betrachtet
bild1.jpg
bild1.jpg (52.96 KiB) 3462 mal betrachtet

Benutzeravatar
juelin
Beiträge: 237
Registriert: Sa 24. Jul 2021, 18:03
OS, Lazarus, FPC: Linux Ubuntu 22. Windows 10 Delphi 11.3 (L 0.9.xy FPC 2.2.z)
CPU-Target: 64Bit
Wohnort: Mannheim

Re: Frage zu StringGrid

Beitrag von juelin »

nächste bilder
Dateianhänge
bild6.jpg
bild6.jpg (41.98 KiB) 3461 mal betrachtet
bild5.jpg
bild5.jpg (45.24 KiB) 3461 mal betrachtet
bild4.jpg
bild4.jpg (47.11 KiB) 3461 mal betrachtet

Benutzeravatar
juelin
Beiträge: 237
Registriert: Sa 24. Jul 2021, 18:03
OS, Lazarus, FPC: Linux Ubuntu 22. Windows 10 Delphi 11.3 (L 0.9.xy FPC 2.2.z)
CPU-Target: 64Bit
Wohnort: Mannheim

Re: Frage zu StringGrid

Beitrag von juelin »

letzte Bilder
Dateianhänge
bild8.jpg
bild8.jpg (44.95 KiB) 3460 mal betrachtet
bild7.jpg
bild7.jpg (44 KiB) 3460 mal betrachtet

Benutzeravatar
Zvoni
Beiträge: 363
Registriert: Fr 5. Jul 2024, 08:26
OS, Lazarus, FPC: Windoof 10 Pro (Laz 2.2.2 FPC 3.2.2)
CPU-Target: 32Bit
Wohnort: BW

Re: Frage zu StringGrid

Beitrag von Zvoni »

Seh ich das richtig, dass egrid zuerst aCol zugewiesen bekommt, und dann in der nächsten Zeile mit aRow überschrieben wird?
Ein System sie alle zu knechten, ein Code sie alle zu finden,
Eine IDE sie ins Dunkel zu treiben, und an das Framework ewig zu binden,
Im Lande Redmond, wo die Windows drohn.

Benutzeravatar
juelin
Beiträge: 237
Registriert: Sa 24. Jul 2021, 18:03
OS, Lazarus, FPC: Linux Ubuntu 22. Windows 10 Delphi 11.3 (L 0.9.xy FPC 2.2.z)
CPU-Target: 64Bit
Wohnort: Mannheim

Re: Frage zu StringGrid

Beitrag von juelin »

ja das ist richtig.
Weil sonst Lazarus eine Warnung ausgibt, dass aCol nie benutzt wird.
Ich ich habe gelernt, das wir Warunungen wie Fehler behandeln sollen.
Deshalb.
Gruß
Jürgen

Soner
Beiträge: 724
Registriert: Do 27. Sep 2012, 00:07
OS, Lazarus, FPC: Win10Pro-64Bit, Immer letzte Lazarus Release mit SVN-Fixes
CPU-Target: x86_64-win64
Wohnort: Hamburg

Re: Frage zu StringGrid

Beitrag von Soner »

Wenn es dir wichtig ist, dass der Benutzer eine Zelle explizit auswählt und nicht mit Cursortasten Auswahl(COL/ROW) verändert um an die Zielzelle zu gelangen, dann vergesse OnSelectCell. Verwende Mausklick- und Keydown-Event.
Eigentlich sollte OnSelectCell in OnFocusChanged o.ä. umbenannt werden, weil sobald aus irgendeinem Grund TStringGrid.Col oder TStringGrid.Row geändert wird, dann wird OnSelectCell ausgelöst.
Stell dir vor, dass man bei jedem Zellenauswahl eine eine Datei lädt oder SQL-Abfrage tätigt und der Benutzer möchte die Zelle 20,50 anschauen, dafür bewegt er mit Cursortasten von der Zelle 1,1 dorthin, viel Spaß... Ich hatte so einen Fall deshalb verwende ich seitdem Keydown- und Mausklick-Event dafür, siehe Beispielprogramm.
OnUserSelected-pub.zip
(2.63 KiB) 127-mal heruntergeladen

Benutzeravatar
juelin
Beiträge: 237
Registriert: Sa 24. Jul 2021, 18:03
OS, Lazarus, FPC: Linux Ubuntu 22. Windows 10 Delphi 11.3 (L 0.9.xy FPC 2.2.z)
CPU-Target: 64Bit
Wohnort: Mannheim

Re: Frage zu StringGrid

Beitrag von juelin »

Danke Soner ,
das hat tatsächlich funktioniert. (Wunder, Wunder, Wunder........)
Ich komme ja von Delphi.
Und bei Delphi gibt es ja auch das Ereignis OnSelectedCell.
Und bei Delphi funktioniert das auch.
Warum nich in Lazarus?????????????????
Da sollten die Entwickler nochmal ran.
Na ja wie auch immer.
Danke für Deine Hilfe.
Schönen Advent wümsche ich.
Gruß
Jürgen

Antworten