ValueListEditor und FixedCols

Rund um die LCL und andere Komponenten
Antworten
Geronimo
Beiträge: 24
Registriert: Sa 1. Feb 2025, 23:22
OS, Lazarus, FPC: Winux (L 3.6.0 FPC 3.2.2)
CPU-Target: 64Bit
Wohnort: Hamburg

ValueListEditor und FixedCols

Beitrag von Geronimo »

Moin,

wenn ich einen ValueListEditor zur Entwurfszeit erstelle und FixedCols := 1 (im Objektinspektor) setze, wird die FixedCols-Einstellung bei der Ausführung
des Programms ignoriert und alle Spalten erscheinen mit der normalen Hintergrundfarbe.
Wenn ich per Programmcode FixedCols := 1 setze, erscheint die erste Spalte tatsächlich mit der Hintergrundfarbe für Fixed Cols.

Ist das ein Feature und so gewollt oder mache ich was falsch?

(Dieses Verhalten macht mir nichts aus, erzeugt nur halt eine zusätzliche Zeile Code.)

Gruß
Geronimo
Die Welt ist linear, rechteckig und gaussverteilt.

Benutzeravatar
fliegermichl
Lazarusforum e. V.
Beiträge: 1639
Registriert: Do 9. Jun 2011, 09:42
OS, Lazarus, FPC: Lazarus Fixes FPC Stable
CPU-Target: 32/64Bit
Wohnort: Echzell

Re: ValueListEditor und FixedCols

Beitrag von fliegermichl »

Ich würde sagen, daß ist ein Bug.
Im Constructor Create wird FixedCols auf 0 gesetzt und bei der Property Definition wird default auf 1 gesetzt.
Das bedeutet, daß die Änderung von 0 auf 1 auch nicht im lfm gespeichert wird. Wenn du das Projekt schliesst und
nachher in Lazarus neu öffnest, steht FixedCols wieder auf 0.

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

Re: ValueListEditor und FixedCols

Beitrag von wp_xyz »

Könnte jemand dafür einen Bug-Report schreiben? Ich vermute fast, dass mit der Änderung des Default-Wertes die Geschichte nicht zu Ende ist. Es gibt nämlich auch noch die Option doKeyColFixed in DisplayOptions, die zumindest verhindert, dass man die 1. Spalte editieren kann. Aber wenn man FixedCols auf 1 hat (also 1.Spalte grau) und doKeyColFixed in DisplayOptions entfernt, so dass die Spalte editierbar wird, kann man trotzdem nichts reinschreiben, weil FixedCols das verhindert. Die beiden Properties müssten besser zusammenarbeiten.

Geronimo
Beiträge: 24
Registriert: Sa 1. Feb 2025, 23:22
OS, Lazarus, FPC: Winux (L 3.6.0 FPC 3.2.2)
CPU-Target: 64Bit
Wohnort: Hamburg

Re: ValueListEditor und FixedCols

Beitrag von Geronimo »

...
ach ja richtig. Ich vergaß zu erwähnen, dass in meiner eingangs beschriebenen Situation doKeyColFixed gesetzt war.
Dadurch war die erste Spalte nicht editierbar, aber halt in der falschen Farbe.

wp_xyz hat Recht. Die Sache ist nicht erledigt, wenn man nur im Creator FixedCols := 1 setzt.

Im Setter von FixedCols findet nur die Bereichsprüfung statt:

Code: Alles auswählen

procedure TValueListEditor.SetFixedCols(const AValue: Integer);
begin
  if (AValue in [0,1]) then
    inherited SetFixedCols(AValue);
end; 
Konsequenterweise müsste man hier auch die DisplayOptions anpassen, analog wie bei FixedRows.

Im Setter für die DisplayOptions wird doKeyColFixed gar nicht behandelt.

Letztlich sollte FixedCols := 1 äquivalent zum Setzen der Option doKeyColFixed sein.
Erscheint mir etwas doppelt gemoppelt, hat aber sicher einen gewissen Charme, wenn viele Wege
nach Rom führen. Die Wege müssen nur synchronisiert sein, damit man tatsächlich in Rom ankommt und nicht
etwa in Madrid oder Mailand.

Grüße aus Hamburg
Die Welt ist linear, rechteckig und gaussverteilt.

Benutzeravatar
fliegermichl
Lazarusforum e. V.
Beiträge: 1639
Registriert: Do 9. Jun 2011, 09:42
OS, Lazarus, FPC: Lazarus Fixes FPC Stable
CPU-Target: 32/64Bit
Wohnort: Echzell

Re: ValueListEditor und FixedCols

Beitrag von fliegermichl »

wp_xyz hat geschrieben: Fr 21. Feb 2025, 14:54 Könnte jemand dafür einen Bug-Report schreiben? Ich vermute fast, dass mit der Änderung des Default-Wertes die Geschichte nicht zu Ende ist. Es gibt nämlich auch noch die Option doKeyColFixed in DisplayOptions, die zumindest verhindert, dass man die 1. Spalte editieren kann. Aber wenn man FixedCols auf 1 hat (also 1.Spalte grau) und doKeyColFixed in DisplayOptions entfernt, so dass die Spalte editierbar wird, kann man trotzdem nichts reinschreiben, weil FixedCols das verhindert. Die beiden Properties müssten besser zusammenarbeiten.
Ich habe da grad nochmal drübergeschaut.
So wie ich das verstehe, sollte FixedCols von 0 auf 1 gesetzt werden, wenn doKeyColFixed in DisplayOptions enthalten ist.
Dann sind die Keyeinträge zwar zunächst auch nicht editierbar. Das passiert dann erst, wenn man keyEdit in KeyOptions auf true setzt.
Wenn man dann noch bei der Property Definition default von 1 auf 0 setzt, sollte alles wie erwartet funktionieren?

Edit:

Die Property FixedCols wurde bereits bei TCustomGrid definiert und default auf 1 gesetzt. In ValEdit.pas kann man nicht mehr auf das private Feld fFixedCols bzw. SetFixedCols zugreifen.
Die Eigenschaft bei TCustomGrid zu ändern, würde wahrscheinlich Probleme in der Kompatibilität mit sich bringen. Zumal dies bereits bei Delphi 5 so ist.

Edit2:

Ich habe einen Bugreport erstellt. Wenn DoKeyColFixed richtig berücksichtigt ist, dann wird FixedCols automatisch auf 1 gesetzt.

Geronimo
Beiträge: 24
Registriert: Sa 1. Feb 2025, 23:22
OS, Lazarus, FPC: Winux (L 3.6.0 FPC 3.2.2)
CPU-Target: 64Bit
Wohnort: Hamburg

Re: ValueListEditor und FixedCols

Beitrag von Geronimo »

@fliegermichl
In ValEdit.pas kann man nicht mehr auf das private Feld fFixedCols bzw. SetFixedCols zugreifen.
Das glaube ich nicht!
Den Code von TValueListEditor.SetFixedCols hatte ich ja schon gepostet.
Oder hat mir da jemand ein Fake-ValueListEditor untergeschoben? :)
Die Setter/Getter werden alle überbügelt, sprich overrided und die Properties mit gleichem Namen wie beim TStringGrid veröffentlicht.
Am TCustomGrid muss nichts geändert werden.
Zumal dies bereits bei Delphi 5 so ist.
... und war da auch schon eher unbefriedigend.

Danke für den Bugreport. Den Code für den Verbesserungsvorschlag zu schreiben, sollten wir hinbekommen.
Ich habe nur als Hobby-Programmierer keinen Nerv auf gitlab.

LG
Geronimo
Die Welt ist linear, rechteckig und gaussverteilt.

Benutzeravatar
fliegermichl
Lazarusforum e. V.
Beiträge: 1639
Registriert: Do 9. Jun 2011, 09:42
OS, Lazarus, FPC: Lazarus Fixes FPC Stable
CPU-Target: 32/64Bit
Wohnort: Echzell

Re: ValueListEditor und FixedCols

Beitrag von fliegermichl »

Du hast Recht, was SetFixedCols angeht. Aber es gibt kein GetFixedCols.
Ich habe es spasseshalber mal implementiert, aber es funkioniert trotzdem nicht.

Code: Alles auswählen

TValueListEditor = class (TCustomStringGrid)
private
 function GetFixedCols : integer;
published
    property FixedCols : integer read GetFixedCols write SetFixedCols default 0;
end;

implementation 

function TValueListEditor.GetFixedCols: integer;
begin
  Result := inherited FixedCols;
end;
Es compiliert, FixedCols bleibt dennoch bei 0 und wird auch nicht in der lfm gespeichert.

Geronimo
Beiträge: 24
Registriert: Sa 1. Feb 2025, 23:22
OS, Lazarus, FPC: Winux (L 3.6.0 FPC 3.2.2)
CPU-Target: 64Bit
Wohnort: Hamburg

Re: ValueListEditor und FixedCols

Beitrag von Geronimo »

Moin Michael,

GetFixedCols brauche ich doch gar nicht.
Wenn ich wissen will, welchen Wert FixedCols hat, schreibe ich FixedCols, was in TValueListEditor so veröffentlicht ist:

Code: Alles auswählen

published
    ....
    property FixedCols;
    ....
end;
Im Creator des TValueListEditors wird FixedCols := 0 und doKeyColFixed gesetzt.
Passt nicht!
Besser:

Code: Alles auswählen

constructor TValueListEditor.Create(AOwner: TComponent);
begin
  ...
  FixedCols := 1;
  ...
  FDisplayOptions := [doColumnTitles, doAutoColResize, doKeyColFixed];
  ...
end;
Jetzt Setter überbügeln:

Code: Alles auswählen

TValueListEditor = class(TCustomStringGrid)
...
protected
  procedure SetFixedCols(const AValue: Integer); override; 
...
end;

implementation

procedure TValueListEditor.SetFixedCols(const AValue: Integer);
begin
  if (AValue in [0,1]) then begin
   inherited SetFixedCols(AValue);
  
   //synchronize with doKeyColFixed option
   if FixedCols = 0 then 
     DisplayOptions := DisplayOptions - [doKeyColFixed]
   else
     DisplayOptions := DisplayOptions + [doKeyColFixed];
  end;   
end;
Und nun bitte auch noch doKeyColFixed im Setter der DisplayOptions behandeln:

Code: Alles auswählen

procedure TValueListEditor.SetDisplayOptions(const AValue: TDisplayOptions);
begin
  BeginUpdate;
  if (doColumnTitles in DisplayOptions) <> (doColumnTitles in AValue) then
    if doColumnTitles in AValue then begin
      if RowCount < 2 then
        {inherited} RowCount := 2;
      inherited SetFixedRows(1);// don't do FixedRows := 1 here, it wil cause infinite recursion (Issue 0029993)
    end else
      inherited SetFixedRows(0);

  //synchronize with FixedCols new Code
  if (doKeyColFixed in DisplayOptions) <> (doKeyColFixed in AValue) then 
    if doKeyColFixed in AValue then
      inherited SetFixedCols(1)
    else
      inherited SetFixedCols(0);
    //end new Code  

  if (doAutoColResize in DisplayOptions) <> (doAutoColResize in AValue) then
    AutoFillColumns := (doAutoColResize in AValue);

  FDisplayOptions := AValue;
  ShowColumnTitles;
  AdjustRowCount;
  EndUpdate;
end; 
ungetestet dahergeschrieben, so müsste es m.E. funzen.

P.S. Der Default-Wert ist im TCustomStringGrid auf 1 gesetzt und da soll er auch bleiben.
Die Welt ist linear, rechteckig und gaussverteilt.

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

Re: ValueListEditor und FixedCols

Beitrag von wp_xyz »

Wenn ich jetzt, mit etwas Abstand, meinen damaligen Post nochmals Revue passieren lassen, meine ich, dass das nicht richtig war: FixedCols und doKeyColFixed haben nichts miteinander zu tun.

Der ValueListEditor soll den in der Breite verfügbaren Platz komplett mit den beiden Spalten ausfüllen. Dafür gibt es das vom Grid geerbte Property AutoFillColumns - das ändert die Spaltenbreite, so dass das erfüllt ist - in der Regel sind alle Spalten dann gleich breit; beim ValueListEditor ist AutoFillColumns=true und regulär von außen nicht veränderbar. Damit man aber unterschiedliche Spaltenbreiten haben kann, wurde im Grid ein "Priority"-Mechanismus eingeführt: Wenn eine Spalte in der Methode GetAutoFillColumnInfo für den Parameter aPriority einen Wert = 0 liefert, so wird sie in ihrer Breite nicht verändert (siehe Kommentar in TCustomGrid.InternalAutoFillColumns). Wenn nun doKeyColFixed in den DisplayOptions enthalten ist, wird genau das gemacht:

Code: Alles auswählen

procedure TValueListEditor.GetAutoFillColumnInfo(const Index: Integer;
  var aMin, aMax, aPriority: Integer);
begin
  if Index=1 then
    aPriority := 1
  else
  begin
    if doKeyColFixed in FDisplayOptions then
      aPriority := 0
    else
      aPriority := 1;
  end;
end;
Das heißt: Entfernt man doKeyColFixed aus den DisplayOptions, teilt sich die Control-Breite gleichmäßig auf die beiden Spalten auf. Fügt man es ein, bleibt die Breite der 1.Spalte fest, und die 2. Spalte bekommt den Rest.

Die FixedCols-Property dagegen soll primär ermöglichen, dass bei sehr breiten Grids die 1.Spalte durch Scrollen aus dem sichtbaren Bereich verschwinden kann. Das ist durch den AutoFillColumns-Mechanism im ValueListEditor ohnehin nicht möglich. Außerdem ist die FixedCol durch andere Farbgebung visuell hervorgehoben.

Das im 1. Post geschilderte Problem, dass man im ObjectInspector FixedCols nicht setzen kann, liegt darin begründet, dass die Komponente mit einem anderen Wert für FixedCols initialisiert wird (0) als in der Property definiert ist (1, vom Grid geerbt). Wenn der User nun FixedCols auf 1 setzt, dann wird dieser Wert wegen "property FixedCols ... default 1" nicht in die LFM-Datei geschrieben. Beim Lesen kommt dann der im Constructor stehende Wert 0 zur Anwendung - FixedCols bleibt 0, obwohl der User etwas anderes will.

Das kann man beheben, indem man im ValueListEditor den default-Wert neu setzt:

Code: Alles auswählen

type
    TValueListEditor = class(TCustomStringGrid)
    ...
    published
      ...
      property FixedCols default 0;
      ...
    end;

Benutzeravatar
fliegermichl
Lazarusforum e. V.
Beiträge: 1639
Registriert: Do 9. Jun 2011, 09:42
OS, Lazarus, FPC: Lazarus Fixes FPC Stable
CPU-Target: 32/64Bit
Wohnort: Echzell

Re: ValueListEditor und FixedCols

Beitrag von fliegermichl »

wp_xyz hat geschrieben: Mo 14. Apr 2025, 18:42 ...
Das kann man beheben, indem man im ValueListEditor den default-Wert neu setzt:

Code: Alles auswählen

type
    TValueListEditor = class(TCustomStringGrid)
    ...
    published
      ...
      property FixedCols default 0;
      ...
    end;
Ah ok, Danke für die Erklärung. Da ist die Bezeichnung doKeyColFixed etwas irreführend. Es bezieht sich nur auf die Breite der Spalte und nicht deren Darstellung.
Wenn man die Ergänzung der Property FixedCols default 0; gemacht hat, muß man Lazarus neu übersetzen damit es funktioniert.

Antworten