Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   GUI-Design mit VCL / FireMonkey / Common Controls (https://www.delphipraxis.net/18-gui-design-mit-vcl-firemonkey-common-controls/)
-   -   Delphi Virtual TreeView - Anhand des längsten Eintrages die Breite der Spalte anpassen (https://www.delphipraxis.net/191131-virtual-treeview-anhand-des-laengsten-eintrages-die-breite-der-spalte-anpassen.html)

TiGü 12. Dez 2016 13:17

Virtual TreeView - Anhand des längsten Eintrages die Breite der Spalte anpassen
 
Hallo zusammen,

ich setze die Virtual TreeView in der Version 6.4.1 mit Delphi Berlin 10.2 ein.
Ich stehe gerade auf den Schlauch oder bin im Mittagstief, daher brauche ich einen Schubs in die richtige Richtung:

Wo und wie konnte ich nochmal einstellen, dass die Treeview in der Spaltenansicht automatisch die Spaltenbreite anhand der Länge der Einträge anpasst?

Beispiel - Ich habe zur Zeit:
Eintrag 1
Eintrag 2
Eintrag 3

Sehe beim Programmstart aber nur:
Ein...
Ein...
Ein...

Muss ich manuell über TVirtualStringTree.Header.Columns.Count iterieren und die TVirtualTreeColumn.Width setzen?

Brainshock 12. Dez 2016 13:26

AW: Virtual TreeView - Anhand des längsten Eintrages die Breite der Spalte anpassen
 
Probier es mal hier:
http://www.delphipraxis.net/88141-vi...-anpassen.html

TiGü 12. Dez 2016 13:42

AW: Virtual TreeView - Anhand des längsten Eintrages die Breite der Spalte anpassen
 
Hm, nein...nicht so wirklich.
Im Gegenteil, die Spalten sind nun noch schmaler als vorher mit den Tipp aus dem letzten Post des verlinkten Threads:

Delphi-Quellcode:
ATreeView.Header.AutoFitColumns(False);
ATreeView.Header.AutoSizeIndex := -1;

madas 12. Dez 2016 13:51

AW: Virtual TreeView - Anhand des längsten Eintrages die Breite der Spalte anpassen
 
bei Doppelklick zwischen zwei Spalten (vst liegt als Komponente in einem Frame):

Delphi-Quellcode:
vst: TVirtualStringTree;
FmerkOnBeforeCellPaint: TVTBeforeCellPaintEvent;

procedure TFrameVST.vstBeforeGetMaxColumnWidth(Sender: TVTHeader; Column: TColumnIndex; var UseSmartColumnWidth: Boolean);
begin
  if Assigned(vst.OnBeforeCellPaint) then
  begin
    FmerkOnBeforeCellPaint := vst.OnBeforeCellPaint;
    vst.OnBeforeCellPaint := nil;
  end;
end;

procedure TFrameVST.vstAfterGetMaxColumnWidth(Sender: TVTHeader; Column: TColumnIndex; var MaxWidth: Integer);
begin
  if Assigned(FmerkOnBeforeCellPaint) then
  begin
    vst.OnBeforeCellPaint := FmerkOnBeforeCellPaint;
    FmerkOnBeforeCellPaint := nil;
  end;
end;

procedure TFrameVST.vstColumnWidthDblClickResize(Sender: TVTHeader; Column: TColumnIndex; Shift: TShiftState; P: TPoint;
  var Allowed: Boolean);
begin
  if (Allowed) and (Shift = []) then
  begin
    AutoFitColumn(Column);
    Allowed := False;
  end;
end;

procedure TFrameVST.AutoFitColumn(Column: TColumnIndex);
var
  cWidth, hWidth: Integer;
begin
  if [coResizable, coVisible] * vst.Header.Columns[Column].Options = [coResizable, coVisible] then
  begin
    cWidth := vst.GetMaxColumnWidth(Column);
    if (hoVisible in vst.Header.Options) then
    begin
      hWidth := GetMaxHeaderWidth(Column);
      if cWidth < hWidth then
        cWidth := hWidth;
      if cWidth > vst.Header.Columns[Column].MaxWidth then
        cWidth := vst.Header.Columns[Column].MaxWidth;
    end;
    vst.Header.Columns[Column].Width := cWidth;
  end;
end;

Brainshock 12. Dez 2016 14:01

AW: Virtual TreeView - Anhand des längsten Eintrages die Breite der Spalte anpassen
 
Was passiert, wenn du das einstellst?

Code:
ATreeView.Header.Options:= ATreeView.Header.Options + [hoAutoResize];
ATreeView.Header.Options:= ATreeView.Header.Options + [hoColumnResize];
ATreeView.Header.AutoSizeIndex := 0;

Ach, und zu madas -> wtf?

Whookie 12. Dez 2016 14:17

AW: Virtual TreeView - Anhand des längsten Eintrages die Breite der Spalte anpassen
 
Liste der Anhänge anzeigen (Anzahl: 1)
Hab das mal schnell ausprobiert und das sollte eigentlich ganz einfach funktionieren....

TiGü 12. Dez 2016 14:30

AW: Virtual TreeView - Anhand des längsten Eintrages die Breite der Spalte anpassen
 
Zitat:

Zitat von Brainshock (Beitrag 1355924)
Was passiert, wenn du das einstellst?

Code:
ATreeView.Header.Options:= ATreeView.Header.Options + [hoAutoResize];
ATreeView.Header.Options:= ATreeView.Header.Options + [hoColumnResize];
ATreeView.Header.AutoSizeIndex := 0;

Ja, das ist schon besser. Spalte eins nimmt die gesamte sichtbare Breite der Treeview ein.
Falls jedoch mehr Spalten vorhanden sind, werden die in den nicht sichtbaren Bereich geschoben und bleiben schmal.
Gab es denn keine Möglichkeit, dass sich die Treeview selber an den Breiten der Itemtexte (nebst Checkbox etc.) orientiert?

@Whookie:

Was? :spin:
Das hat ja nicht einmal sichtbare Spalten mit Header?!?

Whookie 12. Dez 2016 15:02

AW: Virtual TreeView - Anhand des längsten Eintrages die Breite der Spalte anpassen
 
Liste der Anhänge anzeigen (Anzahl: 1)
Beim mir schon:

Aviator 12. Dez 2016 15:15

AW: Virtual TreeView - Anhand des längsten Eintrages die Breite der Spalte anpassen
 
Zitat:

Zitat von Whookie (Beitrag 1355936)
Beim mir schon:

Also ich seh da keinen Header und keine Spalten. :shock:

@TE: Versuch doch mal folgendes:
Delphi-Quellcode:
vst.Header.AutoFitColumns;
.

Eventuell noch mit den diversen Parametern rumspielen. Das ist auch die Funktion die aufgerufen wird wenn du zwischen 2 Columns einen Doppelklick ausführst und dann bei dem Event OnColumnWidthDblClickResize() den Paramter Allowed auf True stellst.

Hoffe dir geholfen zu haben.

Whookie 12. Dez 2016 15:32

AW: Virtual TreeView - Anhand des längsten Eintrages die Breite der Spalte anpassen
 
Liste der Anhänge anzeigen (Anzahl: 1)
Zitat:

Zitat von Aviator (Beitrag 1355938)
Also ich seh da keinen Header und keine Spalten. :shock:

Gibts ja auch Keine, so ist die Komponente ein einfacher Tree. Aber auch mit Column geht das (hoAutoResize muss gesetzt sein).

EWeiss 12. Dez 2016 16:56

AW: Virtual TreeView - Anhand des längsten Eintrages die Breite der Spalte anpassen
 
Hmm...
Ist es nicht eigentlich so das der Anwender die Max breite festlegt?
Und diese dann beim beenden gespeichert wird?

Das Virtual TreeView hat meines Erachtens schon immer Probleme beim Doppelklick zwischen zwei Einträgen im Header.
Hatte da mal einen SkinEditor geschrieben hat da nie funktioniert, habe es dann sein gelassen.


gruss

Aviator 12. Dez 2016 17:42

AW: Virtual TreeView - Anhand des längsten Eintrages die Breite der Spalte anpassen
 
Zitat:

Zitat von EWeiss (Beitrag 1355949)
Das Virtual TreeView hat meines Erachtens schon immer Probleme beim Doppelklick zwischen zwei Einträgen im Header.

Dann hast du es falsch gemacht. :idea:

Bei mir funktioniert das problemlos. Schau mal in den SourceCode des VST was dort alle abgefragt wird. Du musst die Column Options entsprechend des gewünschten Ergebnisses setzen und auch noch mindestens das Event das ich in #9 genannt habe nutzen.

Wenn du das alles korrekt machst, dann funktioniert auch das automatische Resizen der Column. :stupid:

Vorteil ist eben, dass der Tree z.B. die Breite des Textes automatisch entsprechend seines Canvas ermittelt und dann die größte Breite als ColumnWidth setzt.

EWeiss 12. Dez 2016 17:54

AW: Virtual TreeView - Anhand des längsten Eintrages die Breite der Spalte anpassen
 
Zitat:

Dann hast du es falsch gemacht.
Warum muss ich das codemäßig selber machen?
Bsp. Wenn ich ein TreeView in VB6 auf die Form klatsche und dann den Bereich im Header doppelklicke dann setzt sich die Column automatisch auf den längsten Text.
Da muss ich nichts extra programmieren.

Was ich damit sagen will... Das sollte ein Standard verhalten sein ohne es extra programmieren zu müssen.

gruss

Aviator 12. Dez 2016 18:28

AW: Virtual TreeView - Anhand des längsten Eintrages die Breite der Spalte anpassen
 
Zitat:

Zitat von EWeiss (Beitrag 1355954)
Was ich damit sagen will... Das sollte ein Standard verhalten sein ohne es extra programmieren zu müssen.

Eben nicht. Aber das ist Geschmackssache. Wenn ich eine Funktion aktiviert haben möchte, dann aktiviere ich sie eben. Dafür sind die Events und die ganzen vielen tausend Schalter des VST vorhanden.

Die Komponente hat generell kein "Eigenleben". Man muss ihr haarklein sagen was sie machen soll. Ansonsten passiert da gar nix. Aber das ist genau der Vorteil des VST. Man hat alle Freiheiten. Nur muss man die Funktionen eben richtig nutzen. Dafür hilft beim VST eben sehr oft einen Blick in den SourceCode.

Die ursprüngliche Hilfe des VST kann man eigentlich auch in die Tonne treten. Die CHM Datei ist uralt und die PDF Datei ist mittlerweile auch nur noch für die Standardaktionen gültig. Schade das JamSoftware die nicht weiterpflegt. :?

EWeiss 12. Dez 2016 18:38

AW: Virtual TreeView - Anhand des längsten Eintrages die Breite der Spalte anpassen
 
Zitat:

Eben nicht. Aber das ist Geschmackssache.
Wie du schon sagst.

In VBNet, VB6, C#, C++ und anderen sprachen ist das Standard.
Delphi macht schon immer sein eigen Ding.

gruss

Aviator 12. Dez 2016 18:45

AW: Virtual TreeView - Anhand des längsten Eintrages die Breite der Spalte anpassen
 
Zitat:

Zitat von EWeiss (Beitrag 1355956)
Delphi macht schon immer sein eigen Ding.

Das ist weniger eine Sache von Delphi als von der Komponente. Mike Lischke hat die Funktion einfach nicht als Standard implementiert. Was ich persönlich gut finde.

Aber genug zu dem Thema. Wenn du das als Standardverhalten haben möchtest, dann schreib dir doch schnell eine kleine Ableitung der Komponente die diese Funktion standardmäßig aktiviert hat. :cyclops:


@TE: Hat dir eine der vorgeschlagenen Lösungen weitergeholfen? Mich würde interessieren, ob meine Lösung bei dir das gewünschte Ergebnis erzielt hat. :-D :cyclops:

madas 13. Dez 2016 07:41

AW: Virtual TreeView - Anhand des längsten Eintrages die Breite der Spalte anpassen
 
Zitat:

Zitat von EWeiss (Beitrag 1355949)
Das Virtual TreeView hat meines Erachtens schon immer Probleme beim Doppelklick zwischen zwei Einträgen im Header.

Deshalb verwenden wir diese Variante: #4

Kommentar in unseren Quellen: // selber machen, weil BUG im VST die falsche Spalte verwendet - (12.01.2010)

uligerhardt 13. Dez 2016 07:48

AW: Virtual TreeView - Anhand des längsten Eintrages die Breite der Spalte anpassen
 
Zitat:

Zitat von Brainshock (Beitrag 1355924)
Code:
ATreeView.Header.Options:= ATreeView.Header.Options + [hoAutoResize];
ATreeView.Header.Options:= ATreeView.Header.Options + [hoColumnResize];

Das ist doch ein Set, also lieber so: :mrgreen:
Delphi-Quellcode:
ATreeView.Header.Options := ATreeView.Header.Options + [hoAutoResize, hoColumnResize];

EWeiss 13. Dez 2016 07:50

AW: Virtual TreeView - Anhand des längsten Eintrages die Breite der Spalte anpassen
 
Zitat:

Zitat von madas (Beitrag 1355966)
Zitat:

Zitat von EWeiss (Beitrag 1355949)
Das Virtual TreeView hat meines Erachtens schon immer Probleme beim Doppelklick zwischen zwei Einträgen im Header.

Kommentar in unseren Quellen: // selber machen, weil BUG im VST die falsche Spalte verwendet - (12.01.2010)

Danke für die Info die ist mal Aussage kräftig.
Wusste doch das da etwas im argen ist denn ein normales verhalten ist das nicht.
Und wie schon gesagt sollte eigentlich auch Automatisch ohne zusätzlichen Code gehen. (Events hin oder her)

Scheint ja zu gehen nach dem Beheben des Fehlers.

Danke nochmal.

gruss

TiGü 13. Dez 2016 15:27

AW: Virtual TreeView - Anhand des längsten Eintrages die Breite der Spalte anpassen
 
@Aviator: Danke, mit den AutoFitColumns sieht das ganze schon viel besser aus.

Brainshock 14. Dez 2016 11:15

AW: Virtual TreeView - Anhand des längsten Eintrages die Breite der Spalte anpassen
 
Zitat:

Zitat von uligerhardt (Beitrag 1355967)
Das ist doch ein Set, also lieber so: :mrgreen:
Delphi-Quellcode:
ATreeView.Header.Options := ATreeView.Header.Options + [hoAutoResize, hoColumnResize];

Klugscheißer ;).
Ich habe das einzeln gemacht, wegen der Lesbarkeit und so.

Brainshock 14. Dez 2016 11:22

AW: Virtual TreeView - Anhand des längsten Eintrages die Breite der Spalte anpassen
 
Zitat:

Zitat von TiGü (Beitrag 1356015)
@Aviator: Danke, mit den AutoFitColumns sieht das ganze schon viel besser aus.

Kannst du mal deine Lösung veröffentlichen?

TiGü 14. Dez 2016 11:57

AW: Virtual TreeView - Anhand des längsten Eintrages die Breite der Spalte anpassen
 
Zitat:

Zitat von Brainshock (Beitrag 1356097)
Zitat:

Zitat von TiGü (Beitrag 1356015)
@Aviator: Danke, mit den AutoFitColumns sieht das ganze schon viel besser aus.

Kannst du mal deine Lösung veröffentlichen?

Beachte die letzte Zeile im FormCreate!

Delphi-Quellcode:
unit VST.View;

interface

uses
  System.SysUtils, System.Classes,
  Vcl.Controls, Vcl.Forms, VirtualTrees;

type
  PMyNodeData = ^TMyNodeData;

  TMyNodeData = record
    Caption: string;
  end;

  TForm2 = class(TForm)
    procedure FormCreate(Sender: TObject);
    procedure VstFreeNode(Sender: TBaseVirtualTree; Node: PVirtualNode);
    procedure VstGetText(Sender: TBaseVirtualTree; Node: PVirtualNode; Column: TColumnIndex; TextType: TVSTTextType;
      var CellText: string);
  private
    VST: TVirtualStringTree;
  end;

var
  Form2: TForm2;

implementation

{$R *.dfm}

procedure TForm2.FormCreate(Sender: TObject);
var
  LPr, LP: PVirtualNode;
  LData: PMyNodeData;
begin
  VST := TVirtualStringTree.Create(Self);

  VST.name := 'VST';
  VST.Parent := Self;
  VST.Header.Options := VST.Header.Options + [hoVisible];
  VST.Align := alClient;
  VST.OnFreeNode := VstFreeNode;
  VST.OnGetText := VstGetText;

  with VST.Header.Columns.Add do
  begin
    Position := 0;
    Width := 10;
    Text := 'Spalte 1';
    Visible := True;
  end;

  with VST.Header.Columns.Add do
  begin
    Position := 1;
    Width := 10;
    Text := 'Spalte 2';
    Visible := True;
  end;

  VST.NodeDataSize := SizeOf(TMyNodeData);
  LPr := VST.AddChild(nil);
  LData := VST.GetNodeData(LPr);
  LData.Caption := 'Eintrag 1';

  LPr := VST.AddChild(nil);
  LData := VST.GetNodeData(LPr);
  LData.Caption := 'Eintrag 2';

  LPr := VST.AddChild(nil);
  LData := VST.GetNodeData(LPr);
  LData.Caption := 'Eintrag 3 1/4';

  LPr := VST.AddChild(nil);
  LData := VST.GetNodeData(LPr);
  LData.Caption := 'Hallo Welt';

  LPr := VST.AddChild(LPr);
  LData := VST.GetNodeData(LPr);
  LData.Caption := 'Hallo Welt';

  VST.FullExpand();

  VST.Header.AutoFitColumns; // <---- das ist der entscheide Punkt!
end;

procedure TForm2.VstFreeNode(Sender: TBaseVirtualTree; Node: PVirtualNode);
var
  LPData: PMyNodeData;
begin
  LPData := Sender.GetNodeData(Node);
  Finalize(LPData^);
end;

procedure TForm2.VstGetText(Sender: TBaseVirtualTree; Node: PVirtualNode; Column: TColumnIndex; TextType: TVSTTextType;
  var CellText: string);
var
  LData: PMyNodeData;
begin
  LData := VST.GetNodeData(Node);
  if TextType = ttNormal then
    CellText := LData.Caption;
end;

end.

uligerhardt 14. Dez 2016 13:09

AW: Virtual TreeView - Anhand des längsten Eintrages die Breite der Spalte anpassen
 
Zitat:

Zitat von Brainshock (Beitrag 1356095)
Zitat:

Zitat von uligerhardt (Beitrag 1355967)
Das ist doch ein Set, also lieber so: :mrgreen:
Delphi-Quellcode:
ATreeView.Header.Options := ATreeView.Header.Options + [hoAutoResize, hoColumnResize];

Klugscheißer ;).
Ich habe das einzeln gemacht, wegen der Lesbarkeit und so.

Lesbarkeit... pah! :P

Aviator 14. Dez 2016 13:32

AW: Virtual TreeView - Anhand des längsten Eintrages die Breite der Spalte anpassen
 
Zitat:

Zitat von TiGü (Beitrag 1356103)
Zitat:

Zitat von Brainshock (Beitrag 1356097)
Zitat:

Zitat von TiGü (Beitrag 1356015)
@Aviator: Danke, mit den AutoFitColumns sieht das ganze schon viel besser aus.

Kannst du mal deine Lösung veröffentlichen?

Beachte die letzte Zeile im FormCreate!

Das Verhalten von AutoFitColumns() lässt sich durch die einzelnen Column Options noch entsprechend anpassen.


Hier mal ein Auszug aus dem VST SourceCode:

Delphi-Quellcode:
procedure TVTHeader.AutoFitColumns(Animated: Boolean = True; SmartAutoFitType: TSmartAutoFitType = smaUseColumnOption;
  RangeStartCol: Integer = NoColumn; RangeEndCol: Integer = NoColumn);

  //--------------- local functions -------------------------------------------

  function GetUseSmartColumnWidth(ColumnIndex: TColumnIndex): Boolean;

  begin
    Result := False;
    case SmartAutoFitType of
      smaAllColumns:
        Result := True;
      smaNoColumn:
        Result := False;
      smaUseColumnOption:
        Result := coSmartResize in FColumns.Items[ColumnIndex].FOptions;
    end;
  end;

  //----------------------------------------------------------------------------

  procedure DoAutoFitColumn(Column: TColumnIndex);

  begin
    with FColumns do
      if ([coResizable, coVisible] * Items[FPositionToIndex[Column]].FOptions = [coResizable, coVisible]) and
            DoBeforeAutoFitColumn(FPositionToIndex[Column], SmartAutoFitType) and not TreeView.OperationCanceled then
      begin
        if Animated then
          AnimatedResize(FPositionToIndex[Column], Treeview.GetMaxColumnWidth(FPositionToIndex[Column],
            GetUseSmartColumnWidth(FPositionToIndex[Column])))
        else
          FColumns[FPositionToIndex[Column]].Width := Treeview.GetMaxColumnWidth(FPositionToIndex[Column],
            GetUseSmartColumnWidth(FPositionToIndex[Column]));

        DoAfterAutoFitColumn(FPositionToIndex[Column]);
      end;
  end;

  //--------------- end local functions ----------------------------------------

var
  I: Integer;
  StartCol,
  EndCol: Integer;

begin
  ...
end;
Je nachdem welcher SmartAutoFitType übergeben wird, werden entweder die globalen Standardeinstellungen oder aber Columnspezifische Einstellungen verwendet.

Codehunter 14. Dez 2016 14:53

AW: Virtual TreeView - Anhand des längsten Eintrages die Breite der Spalte anpassen
 
Womit mal wieder bewiesen wäre: It's not a Bug, it's a Fietscher :-D

Aviator 14. Dez 2016 14:58

AW: Virtual TreeView - Anhand des längsten Eintrages die Breite der Spalte anpassen
 
Zitat:

Zitat von Codehunter (Beitrag 1356127)
Womit mal wieder bewiesen wäre: It's not a Bug, it's a Fietscher :-D

Richtig. Man muss die Komponente nur richtig benutzen. Dann funktioniert sie auch wie gewünscht. :roll:

Codehunter 14. Dez 2016 15:30

AW: Virtual TreeView - Anhand des längsten Eintrages die Breite der Spalte anpassen
 
Wobei ich anmerken muss, eine RICHTIGE Bedienung bzw. Verwendung setzt auch eine ordentliche Referenz-Doku voraus. Und die ist beim VST... sagen wir mal... ausbaufähig ^^

Aviator 14. Dez 2016 15:35

AW: Virtual TreeView - Anhand des längsten Eintrages die Breite der Spalte anpassen
 
Zitat:

Zitat von Codehunter (Beitrag 1356139)
Wobei ich anmerken muss, eine RICHTIGE Bedienung bzw. Verwendung setzt auch eine ordentliche Referenz-Doku voraus. Und die ist beim VST... sagen wir mal... ausbaufähig ^^

Das ist wahr. Habe ich ja auch schon in #14 angemeckert. Aber ich muss auch sagen, dass die Komponente nicht von jedem Neuling/Anfänger genutzt werden kann. Um ein ordentliches Bild mit der Komponente zustande zu bringen muss man schon eine gewisse Erfahrung mitbringen. Und zudem braucht es auch einiges an Arbeitszeit um mit der Komponente schnell und effektiv arbeiten zu können. Und wenn man so weit ist, dann schaut man sowieso in den SourceCode. Der ist in dem Fall dann sogar aussagekräftiger. Zumindest geht es mir so. Ich habe allerdings auch schonmal in die PDF Datei reingeschaut wenn ich mir unter einer Einstellung oder einem Event so rein gar nix vorstellen konnte. Allerdings war das dann mehr ein Glücksspiel ob dort wirklich etwas drin steht. :lol:


Alle Zeitangaben in WEZ +1. Es ist jetzt 07:03 Uhr.

Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024-2025 by Thomas Breitkreuz