StringGrid und SelectEditor

Rund um die LCL und andere Komponenten
Antworten
Ronny58
Beiträge: 90
Registriert: So 27. Apr 2014, 20:35

StringGrid und SelectEditor

Beitrag von Ronny58 »

Hallo Zusammen,

ich habe ein Stringgrid und dort im SelectEditor ein TEdit:

Code: Alles auswählen

procedure TfAttrEdit.sgAttrEditSelectEditor(Sender: TObject; aCol,
  aRow: Integer; var Editor: TWinControl);
begin
  if (sgAttrEdit.Row > 0) AND (aCol < 12) then
  begin
    Editor := edAttrName;
    sgAttrEdit.Editor:=edAttrName;
    Editor.BoundsRect := sgAttrEdit.CellRect(aCol,aRow);
    edAttrName.Caption := sgAttrEdit.Cells[aCol,aRow];
    Editor.SetFocus;
  end;
end;
Das TEdit nutze ich, da ich bei der Eingabe eine komplexe Validierung durchführe und es im Fehlerfall rot einfärbe. Ich erlaube in diesem Fall nur ein Escape, der den Eintrag im Stringgrid sofort wieder entfernt (soweit neu eingefügt) oder ein geänderter Wert, der aber fehlerhafter Ist, auf seinen Ursprungswert zurück gesetzt wird.

Dazu habe ich das TEdit mit dem Name "edAttrName" auf meinem Formular platziert.
Der Editor wir mit jeder neu eingefügten Zeile sofort in aRow und aCol= 4 aktiviert.

Ich habe jetzt ein Problem, wenn das StringGrid leer ist (RowCount = 1, FixedRow = 1).
Wenn ich die erste Zeile im StringGrid einfüge (aRow = 1) wird das TEdit nicht in in der Zelle aCol und aRow platziert . Das TEdit wird zwar angezeigt und funktioniert auch, allerdings dort, wo ich auf dem Formular während der Entwicklung platziert habe.
Ab der zweiten neuen Zeile (RowCount > 2) wird der Editor dann korrekt im Grid platziert.

Ich hab mir eine Breakpoint auf "if (sgAttrEdit.Row > 0) AND (aCol < 12) then" gesetzt. Wird die erste Zeile ins Grid eingefügt, wird die Procedure "SelectEditor" gar nicht aufgerufen.

Jemand einen Tip, wie ich das hin bekomme?

Benutzeravatar
Winni
Beiträge: 1577
Registriert: Mo 2. Mär 2009, 16:45
OS, Lazarus, FPC: Laz2.2.2, fpc 3.2.2
CPU-Target: 64Bit
Wohnort: Fast Dänemark

Re: StringGrid und SelectEditor

Beitrag von Winni »

Hallo!

Das bedeutet doch, dass .sgAttrEditSelectEditor ausgeführt wird, bevor die Zeile eingefügt wird.

Entweder Du bekommst es hin, dass die Reihenfolge geändert wird.
Oder Du musst die Kondition ändern auf

Code: Alles auswählen

if (sgAttrEdit.Row > sgAttrEdit.FixedRows) AND (aCol ......
Winni

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

Re: StringGrid und SelectEditor

Beitrag von wp_xyz »

Ich verstehe mal wieder die Fehler-Beschreibung nicht. Kannst du nicht ein kleines Projekt mit einem Grid und dem geänderten Zell-Editor zusammenklicken, in dem der Fehler auftritt? Wenn du das hier hochlädst (als zip über "Dateianhänge"), können wir uns das genauer ansehen und finden sicher schnell eine Lösung.

Sieben
Beiträge: 202
Registriert: Mo 24. Aug 2020, 14:16
OS, Lazarus, FPC: Ubuntu Xenial 32, Lazarus 2.2.0, FPC 3.2.2
CPU-Target: i386

Re: StringGrid und SelectEditor

Beitrag von Sieben »

Was mir an dem Code auffällt: du solltest in einem Event immer möglichst die übergebenen Parameter nutzen. Es ist nicht nötig, das Grid in der ersten Zeile nach seiner Row zu fragen, die hat es dir mit aRow ja gerade mitgeteilt. Es könnte sich bei den Werten ja auch um berechnete bzw bereinigte handeln. Und wenn es dir ein 'var Editor' zur Verfügung stellt, ist es nicht nötig ihm anschließend zusätzlich nochmal den Editor zuzuweisen und kann ebenfalls zu Komplikationen führen. Und drittens ist auch SetFocus wenig hilfreich - bei meinem kleinen Probeprojekt gab's da bei der zweiten Zelle schon eine Exception. Das Grid sorgt normalerweise schon für den Fokus, erst wenn nicht, solltest du das in Erwägung ziehen. Also erst mal wäre das:

Code: Alles auswählen

procedure TForm1.GridSelectEditor(Sender: TObject; aCol, aRow: Integer;
  var Editor: TWinControl);
begin
  if (aRow > 0) and (aCol < 3) then
  begin
    Edit.BoundsRect := Grid.CellRect(aCol,aRow);
    Edit.Text := Grid.Cells[aCol,aRow];
    Editor := Edit;
  end;
end;         
mE völlig ausreichend (und auch 'sicherer'). Um dein Problem aber wirklich nachvollziehen zu können, müsste man mehr über die 'Umstände' wissen, also zB die Einstellungen des Grids und die 'allgemeine Programmsituation'. Insofern ist ein kleines Probeprojekt zum nachvollziehen immer hilfreich, wie ja auch schon von wp_xyz angeregt. Und oft zeigt sich dann beim Erstellen eines solchen, dass das Problem, wenn isoliert, gar nicht auftaucht und man hat damit schon Hinweise zur Lösung.

Ronny58
Beiträge: 90
Registriert: So 27. Apr 2014, 20:35

Re: StringGrid und SelectEditor

Beitrag von Ronny58 »

Sorry, das ich mich erst jetzt wieder melde.

Ich hab versucht mein Programm abzuspecken, um es zu posten. Da wird es dann noch merkwürdiger. Daher ich fange bei 0 neu an.
Folgendes will ich erreichen:

Ich möchte im StringGrid die Tasten abfangen.
- Befinde ich mich in der letzten Zeile, soll bei "Pfeil runter" eine neue hinzugefügt werden und automatisch der Editor aktiviert werden.
- Mit den Tasten A-Z und 0-9 soll automatisch der Editor aktiviert werden.
- Mit Enter wird TEdit mit dem Zelleninhalt vorbelegt und automatisch der Editor aktiviert werden.

Das TEdit brauche ich für das OnChange-Ereignis zur Prüfung der Eingabe. Eine fehlerhafte Eingabe soll:
- das Eingabefeld rot markieren
- keine Enter-Taste erlauben
- bei Escape eine neu eingefügte Zeile löschen oder den Ursprungsinhalt der Zelle erhalten.

Entweder ist die Eingabe ok oder es bleibt nur der Abbruch.

Dazu habe ich OnKeyDown verwendet:

Code: Alles auswählen

procedure TForm1.sgAttrEditKeyDown(Sender: TObject; var Key: Word;
  Shift: TShiftState);
begin
  if Key = VK_DOWN then
  begin
    if sgAttrEdit.Row = sgAttrEdit.RowCount-1 then
    begin
      if sgAttrEdit.Row = sgAttrEdit.RowCount-1 then sgAttrEdit.RowCount := sgAttrEdit.RowCount + 1;
      // hier Editor aktivieren
    end;
  end
  else if ((Key >= VK_0) and (Key <= VK_9)) or ((Key >= VK_A) and (Key <= VK_Z)) then
  begin
    edAttrName.Caption := chr(key);
    edAttrName.SelStart := Length(edAttrName.Text);
    // hier Editor aktivieren
  end
  else if Key = VK_Return then
  begin
    edAttrName.SelStart := 1;
    edAttrName.SelLength := Length(edAttrName.Text);
    // hier Editor aktivieren
  end;
end;
Also meine Frage: Wie aktiviere ich in OnKeyDown den Editor, so wie ich ihn in OnSelectEditor definiert habe?
Oder anders gefragt wie löse ich das OnSelectEditor-Ereignis aus?

Socke
Lazarusforum e. V.
Beiträge: 3158
Registriert: Di 22. Jul 2008, 19:27
OS, Lazarus, FPC: Lazarus: SVN; FPC: svn; Win 10/Linux/Raspbian/openSUSE
CPU-Target: 32bit x86 armhf
Wohnort: Köln
Kontaktdaten:

Re: StringGrid und SelectEditor

Beitrag von Socke »

Ronny58 hat geschrieben:
Mo 5. Okt 2020, 17:00
Ich möchte im StringGrid die Tasten abfangen.
- Befinde ich mich in der letzten Zeile, soll bei "Pfeil runter" eine neue hinzugefügt werden und automatisch der Editor aktiviert werden.
Das kann das TStringGrid schon von Haus aus. Du musst nur goAutoAddRows in Options aufnehmen.
goEditing sollte ja ohnehin bereits aktiv sein. Falls du auch neue Zeilen hinzufügen möchtest, wenn die letzte Zeile leer ist, hilft dir goAutoAddRowSkipContentCheck.
Ronny58 hat geschrieben:
Mo 5. Okt 2020, 17:00
Das TEdit brauche ich für das OnChange-Ereignis zur Prüfung der Eingabe.
Hier hast du das Event OnValidateEntry. Das Prüfergebnis kannst du dir in einer Extravariablen des Forms speichern und beim OnPrepareCanvas oder OnDrawCell in die farbliche Markierung einfließen lassen.
MfG Socke
Ein Gedicht braucht keinen Reim//Ich pack’ hier trotzdem einen rein

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

Re: StringGrid und SelectEditor

Beitrag von wp_xyz »

Socke hat geschrieben:
Mo 5. Okt 2020, 19:35
Hier hast du das Event OnValidateEntry. Das Prüfergebnis kannst du dir in einer Extravariablen des Forms speichern und beim OnPrepareCanvas oder OnDrawCell in die farbliche Markierung einfließen lassen.
Allerdings meine ich, dass man die Grid-Zelle hier überhaupt nicht sieht, weil ja der Editor aktiv ist und drüber liegt. Ich denke, es ist besser, im OnSelectEditor die Hintergrundfarbe des Editors (der ja ein TEdit ist) auf rot zu setzen (wobei es wiederum die Frage ist, ob das wegen der Widgetset-Restriktionen bei jedem OS und für alle Zeiten funktioniert).

Ronny58
Beiträge: 90
Registriert: So 27. Apr 2014, 20:35

Re: StringGrid und SelectEditor

Beitrag von Ronny58 »

TestGrid.7z
(60.38 KiB) 107-mal heruntergeladen
So, jetzt habe ich eine einfache Demo meines Problems hinbekommen.
Da ist noch ein alternativer Code am Ende, aber der, um den es sich dreht ist gleich am Anfang:

Code: Alles auswählen

// -----------------------------------------------------------------------------
// Anfang Grid mit SelectEditor

procedure TForm1.GridWithEditorSelectEditor(Sender: TObject; aCol,
  aRow: Integer; var Editor: TWinControl);
begin
  if (aRow > 0) and (aCol = 4) then
  begin
    GridEditor.BoundsRect := GridWithEditor.CellRect(aCol,aRow);
    GridEditor.Text := GridWithEditor.Cells[aCol,aRow];
    Editor := GridEditor;
  end;
end;

procedure TForm1.GridWithEditorKeyDown(Sender: TObject; var Key: Word;
  Shift: TShiftState);
begin
  if (Key = VK_DOWN) and (GridWithEditor.Row = GridWithEditor.RowCount-1) then
  begin
    GridWithEditor.RowCount:=GridWithEditor.RowCount+1;
    GridWithEditor.EditorMode:=True;
  end;
end;

// Ende Grid mit SelectEditor
// -----------------------------------------------------------------------------
Auf Col 4 ist eingeschränkt, da nur in der Spalte "Name" der Editor verwendet werden soll.
Zum testen bitte im leeren Grid mit der Pfeil-Runter-Taste eine neue Zeile einfügen. Ergebnis: neue Zeile ist da, Editor nicht aktiv.
Dann eine zweite Zeile mit der Pfeil-Runter-Taste einfügen. Ergebnis: neue Zeile ist da, Editor ist aktiv.

Es klappt nur bei der aller ersten Zeile nicht.

Sieben
Beiträge: 202
Registriert: Mo 24. Aug 2020, 14:16
OS, Lazarus, FPC: Ubuntu Xenial 32, Lazarus 2.2.0, FPC 3.2.2
CPU-Target: i386

Re: StringGrid und SelectEditor

Beitrag von Sieben »

Wie sind die Grideinstellungen? Anfangsbedingungen wie FixedRows, RowCount und die von den Defaults abweichenden Options...?

Sieben
Beiträge: 202
Registriert: Mo 24. Aug 2020, 14:16
OS, Lazarus, FPC: Ubuntu Xenial 32, Lazarus 2.2.0, FPC 3.2.2
CPU-Target: i386

Re: StringGrid und SelectEditor

Beitrag von Sieben »

Sorry, steh wohl ein bisschen auf dem Schlauch heute...

Sieben
Beiträge: 202
Registriert: Mo 24. Aug 2020, 14:16
OS, Lazarus, FPC: Ubuntu Xenial 32, Lazarus 2.2.0, FPC 3.2.2
CPU-Target: i386

Re: StringGrid und SelectEditor

Beitrag von Sieben »

Offensichtlich wird OnSelectEditor für die erste Zeile so tatsächlich nicht ausgelöst. Gibt es einen Grund, warum du nicht mit einer leeren Zeile von Anfang an starten möchtest? Ich fände das auch intuitiver. Und dann ist der Editor auch beim ersten Reinklicken da, und du könntest das Anfügen von Zeilen auch den goAutoAdds überlassen.

Antworten