AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Zurück Delphi-PRAXiS Programmierung allgemein GUI-Design mit VCL / FireMonkey / Common Controls Delphi TVirtualStringTree AutoFitColumns erste Spalte wird nicht angepasst

TVirtualStringTree AutoFitColumns erste Spalte wird nicht angepasst

Ein Thema von TUX_der_Pinguin · begonnen am 4. Apr 2017 · letzter Beitrag vom 6. Apr 2017
Antwort Antwort
Seite 4 von 5   « Erste     234 5   
Aviator

Registriert seit: 3. Jun 2010
1.610 Beiträge
 
Delphi 10.3 Rio
 
#31

AW: TVirtualStringTree AutoFitColumns erste Spalte wird nicht angepasst

  Alt 6. Apr 2017, 10:42
Haste vollkommen recht. Siehe mein Edit oben. Hat sich jetzt zeitlich nur überschnitten.


EDIT:

Dein Abwählen der Node hat intern ein Invalidate ausgelöst. Somit ist der Text auf dem Canvas neu gezeichnet worden und die Textbreite kann ermittelt werden. Der Tree weiß ja nicht, wie er auf deine internen Daten zugreifen soll.
Das ist so nicht ganz richtig. Dann müsste der VST die einmal gezeichnete Textbreite intern puffern. Tut er aber nicht. Tatsächlich holt er sich per GetTextMetrics regelmäßig die tatsächlichen Textbreiten vom jeweiligen DeviceContext und berechnet auch jedesmal neu. Da dürfte es eigentlich gar keine Rolle spielen ob der Node focused ist oder nicht. Welcher Text für die Berechnung verwendet werden soll wird über den Event OnGetText gesteuert. Heißt: Wird GetMaxColumnWidth aufgerufen, dann holt sich VST über OnGetText den passenden String und kalkuliert über GetTextMetrics neu.
Hmm. Von Puffern hatte ich ja auch nichts geschrieben, oder?
Es ist so, dass bei jeder Änderung des Trees, die die Oberfläche betrifft, ein Invalidate des entsprechenden Bereiches ausgelöst wird. Bei ihm wurde das gemacht, weil er die FocusedNode Property gesetzt hat und somit die "Focused Umrandung" (keine Ahnung wie ich das besser beschreiben soll, diese gepunktete Linie die angibt, dass die Node den Focus hat) auf eine andere Node bzw. auf keine Node neu gezeichnet wurde. Hierdurch wurde dann auch gleich wieder das Berechnen der Spaltenbreite ausgelöst.

Die vorherige Spaltenbreite bzw. die Breite der einzelnen Inhalte muss der Tree ja auch nicht kennen. Er durchläuft lediglich die Nodes und holt sich per GetText Event den Inhalt. Die Breite dieses Textes wird dann Canvas bezogen errechnet. Der größte Wert wird dann als Spaltenbreite übernommen. Dazu kommt dann noch TextMargins + NodeLevel(Node) * Indent usw.
  Mit Zitat antworten Zitat
Benutzerbild von Codehunter
Codehunter

Registriert seit: 3. Jun 2003
Ort: Thüringen
2.272 Beiträge
 
Delphi 10.4 Sydney
 
#32

AW: TVirtualStringTree AutoFitColumns erste Spalte wird nicht angepasst

  Alt 6. Apr 2017, 10:58
Ich denke der gedankliche Fehler hierbei ist, dass der gezeichnete Cell-Content in irgendeiner Weise Auswirkung auf das Ergebnis von GetMaxColumnWidth hätte. Dem ist aber IMHO nicht so. Vielmehr sind gerade solche Dinge wie FocusBorder (das gepunktete Dingens) von ihrem Platzbedarf her von vornherein sozusagen reserviert (teilweise über VST-Properties konfigurierbar). Das einzige wo sich hier die MainColumn von anderen unterscheidet ist der dynamische Teil mit den Indents. Also Node expanded oder nicht, mit Childnodes oder nicht, mit NodeButton oder nicht usw.

Deshalb bin ich auch der Ansicht, dass ein InvalidateNode keine Auswirkungen auf das Ergebnis von GetMaxColumnWidth haben dürfte. Es sei denn, man würde eventgesteuert die externen Daten zwischendurch verändern. Was ja, wie bereits geschrieben, nur anhand des konkreten Projektes nachvollziehbar ist und nicht allein anhand des VST-Codes den wir alle haben.
Ich mache grundsätzlich keine Screenshots. Schießen auf Bildschirme gibt nämlich hässliche Pixelfehler und schadet der Gesundheit vom Kollegen gegenüber. I und E zu vertauschen hätte den selben negativen Effekt, würde aber eher dem Betriebsklima schaden
  Mit Zitat antworten Zitat
Aviator

Registriert seit: 3. Jun 2010
1.610 Beiträge
 
Delphi 10.3 Rio
 
#33

AW: TVirtualStringTree AutoFitColumns erste Spalte wird nicht angepasst

  Alt 6. Apr 2017, 12:11
Deshalb bin ich auch der Ansicht, dass ein InvalidateNode keine Auswirkungen auf das Ergebnis von GetMaxColumnWidth haben dürfte.
Das ist vollkommen korrekt. GetMaxColumnWidth() berechnet die maximal benötigte Breite um die NodeTexte darin optimal zu zeichnen. Hierbei kommt es darauf an, ob der Aufrufer die Breite aller NodeTexte und nur die der sichtbaren Nodes möchte.

Ein InvalidateNode führt nur dazu, dass der gesamte Tree neu und dementsprechend die im Hintergrund geänderten Daten auf dem Tree gezeichnet werden. Ein Aufruf vom eigentlichen AutoFitColumns() würde ja praktisch implizit ein Invalidate aufrufen.
  Mit Zitat antworten Zitat
TUX_der_Pinguin

Registriert seit: 1. Jun 2005
Ort: Anholt (NRW)
608 Beiträge
 
Delphi 11 Alexandria
 
#34

AW: TVirtualStringTree AutoFitColumns erste Spalte wird nicht angepasst

  Alt 6. Apr 2017, 12:14
Deshalb bin ich auch der Ansicht, dass ein InvalidateNode keine Auswirkungen auf das Ergebnis von GetMaxColumnWidth haben dürfte. Es sei denn, man würde eventgesteuert die externen Daten zwischendurch verändern. Was ja, wie bereits geschrieben, nur anhand des konkreten Projektes nachvollziehbar ist und nicht allein anhand des VST-Codes den wir alle haben.
Naja InvalidateNode() hat aber eine Auswirkung darauf, zumindest soweit das die Berechnung danach funktioniert. Ich weiß doch auch nicht wieso das so ist.
Damit ihr euch das auch ansehen könnt habe ich eine Mini Anwendung (siehe Anhang) gebaut die das Verhalten wie mein eigentliches Projekt aufweist.
Angehängte Dateien
Dateityp: zip VST TEST.ZIP (1,08 MB, 8x aufgerufen)
  Mit Zitat antworten Zitat
madas

Registriert seit: 9. Aug 2007
207 Beiträge
 
#35

AW: TVirtualStringTree AutoFitColumns erste Spalte wird nicht angepasst

  Alt 6. Apr 2017, 12:37
Tja da hat wohl jemand das "^" beim Zugriff auf Data vergessen.

alt:

Delphi-Quellcode:
Node := vstTable.FocusedNode;
  if Assigned(Node) then
  begin
    Data := vstTable.GetNodeData(Node);
    if Assigned(Data) then
    begin
      Data.Name := Data.Name + 'xyz 12345';
      Data.Desc := Data.Desc + 'xyz 12345';
    end;
  end;
so wie es muss:

Delphi-Quellcode:
Node := vstTable.FocusedNode;
  if Assigned(Node) then
  begin
    Data := vstTable.GetNodeData(Node);
    if Assigned(Data) then
    begin
      Data^.Name := Data^.Name + 'xyz 12345';
      Data^.Desc := Data^.Desc + 'xyz 12345';
    end;
  end;
Beim OnGetText genau so. Usw.

Geändert von madas ( 6. Apr 2017 um 12:40 Uhr)
  Mit Zitat antworten Zitat
TUX_der_Pinguin

Registriert seit: 1. Jun 2005
Ort: Anholt (NRW)
608 Beiträge
 
Delphi 11 Alexandria
 
#36

AW: TVirtualStringTree AutoFitColumns erste Spalte wird nicht angepasst

  Alt 6. Apr 2017, 12:43
Tja da hat wohl jemand das "^" beim Zugriff auf Data vergessen.

alt:

Delphi-Quellcode:
Node := vstTable.FocusedNode;
  if Assigned(Node) then
  begin
    Data := vstTable.GetNodeData(Node);
    if Assigned(Data) then
    begin
      Data.Name := Data.Name + 'xyz 12345';
      Data.Desc := Data.Desc + 'xyz 12345';
    end;
  end;
so wie es muss:

Delphi-Quellcode:
Node := vstTable.FocusedNode;
  if Assigned(Node) then
  begin
    Data := vstTable.GetNodeData(Node);
    if Assigned(Data) then
    begin
      Data^.Name := Data^.Name + 'xyz 12345';
      Data^.Desc := Data^.Desc + 'xyz 12345';
    end;
  end;
Beim OnGetText genau so. Usw.
Was heißt vergessen, es funktionierte bisher auch gut ohne. Aber auch mit "^" ändert sich nichts am ursprünglichen Problem, das die erste Spalte nicht angepasst wird wenn ich AutoFitColumns aufrufe.
  Mit Zitat antworten Zitat
Benutzerbild von Codehunter
Codehunter

Registriert seit: 3. Jun 2003
Ort: Thüringen
2.272 Beiträge
 
Delphi 10.4 Sydney
 
#37

AW: TVirtualStringTree AutoFitColumns erste Spalte wird nicht angepasst

  Alt 6. Apr 2017, 13:03
Tja da hat wohl jemand das "^" beim Zugriff auf Data vergessen.
Das hatte ich hier schon bemängelt.
Ich mache grundsätzlich keine Screenshots. Schießen auf Bildschirme gibt nämlich hässliche Pixelfehler und schadet der Gesundheit vom Kollegen gegenüber. I und E zu vertauschen hätte den selben negativen Effekt, würde aber eher dem Betriebsklima schaden
  Mit Zitat antworten Zitat
madas

Registriert seit: 9. Aug 2007
207 Beiträge
 
#38

AW: TVirtualStringTree AutoFitColumns erste Spalte wird nicht angepasst

  Alt 6. Apr 2017, 13:04
Tja da hat wohl jemand das "^" beim Zugriff auf Data vergessen.

alt:

Delphi-Quellcode:
Node := vstTable.FocusedNode;
  if Assigned(Node) then
  begin
    Data := vstTable.GetNodeData(Node);
    if Assigned(Data) then
    begin
      Data.Name := Data.Name + 'xyz 12345';
      Data.Desc := Data.Desc + 'xyz 12345';
    end;
  end;
so wie es muss:

Delphi-Quellcode:
Node := vstTable.FocusedNode;
  if Assigned(Node) then
  begin
    Data := vstTable.GetNodeData(Node);
    if Assigned(Data) then
    begin
      Data^.Name := Data^.Name + 'xyz 12345';
      Data^.Desc := Data^.Desc + 'xyz 12345';
    end;
  end;
Beim OnGetText genau so. Usw.
Was heißt vergessen, es funktionierte bisher auch gut ohne. Aber auch mit "^" ändert sich nichts am ursprünglichen Problem, das die erste Spalte nicht angepasst wird wenn ich AutoFitColumns aufrufe.
Bei michse schon. Hast Du es auch überall angepasst?
  Mit Zitat antworten Zitat
Benutzerbild von Codehunter
Codehunter

Registriert seit: 3. Jun 2003
Ort: Thüringen
2.272 Beiträge
 
Delphi 10.4 Sydney
 
#39

AW: TVirtualStringTree AutoFitColumns erste Spalte wird nicht angepasst

  Alt 6. Apr 2017, 13:29
@TUX_der_Pinguin: Mal dumm gefragt: Verwendest du den VST als Tree oder als Grid? Sprich, brauchst du das ganze Aufklapp-Gedönse überhaupt? Denn wenn nicht, setzt du einfach Header.MainColumn auf 1 und der Fehler ist umgangen.

Jetzt kann ich zumindest das Problem nachvollziehen. Hinzu kommt, die drei "Abkürzungspünktchen" werden auch nicht korrekt angezeigt wenn man die Spalte 0 danach manuell verkleinert. Erst nach einem Invalidate (implizit durch Fokuswechsel) wird der Node richtig initialisiert. Das spräche ja dafür, dass der VST doch irgendwas intern puffert. Sehr seltsam.

Besonders deutlich wird das Problem, wenn man TreeOptions.StringOptions.toShowStaticText setzt. Dann überlappen sich in Spalte 0 sogar die Texte. Das ist Mumpitz. Scheint also ein Käferchen im VST zu sein.

Ich würde vorerst bei meiner Vermutung bleiben, dass da irgendwo im VST eine hartcodierte MainColumn = 0 verblieben ist.
Ich mache grundsätzlich keine Screenshots. Schießen auf Bildschirme gibt nämlich hässliche Pixelfehler und schadet der Gesundheit vom Kollegen gegenüber. I und E zu vertauschen hätte den selben negativen Effekt, würde aber eher dem Betriebsklima schaden
  Mit Zitat antworten Zitat
TUX_der_Pinguin

Registriert seit: 1. Jun 2005
Ort: Anholt (NRW)
608 Beiträge
 
Delphi 11 Alexandria
 
#40

AW: TVirtualStringTree AutoFitColumns erste Spalte wird nicht angepasst

  Alt 6. Apr 2017, 13:31
Bei michse schon. Hast Du es auch überall angepasst?
Ja habe ich und nach wie vor bleibt die erste Spalte nur 62px breit obwohl 106px sein müssten.
Delphi-Quellcode:
unit Unit2;

interface

uses
  Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes, Vcl.Graphics,
  Vcl.Controls, Vcl.Forms, Vcl.Dialogs, VirtualTrees, Vcl.StdCtrls;

type
  TMyDataSet = record
    Name: String;
    Desc: String;
  end;
  PMyDataSet = ^TMyDataSet;

type
  TForm2 = class(TForm)
    vstTable: TVirtualStringTree;
    Button1: TButton;
    procedure FormCreate(Sender: TObject);
    procedure vstTableGetText(Sender: TBaseVirtualTree; Node: PVirtualNode;
      Column: TColumnIndex; TextType: TVSTTextType; var CellText: string);
    procedure Button1Click(Sender: TObject);
  private
    { Private-Deklarationen }
  public
    { Public-Deklarationen }
  end;

var
  Form2: TForm2;

implementation

{$R *.dfm}

procedure TForm2.Button1Click(Sender: TObject);
var
  Node: PVirtualNode;
  Data: PMyDataSet;
  
begin

  ShowMessage(IntToStr(vstTable.GetMaxColumnWidth(0, False))); //62px
  ShowMessage(IntToStr(vstTable.GetMaxColumnWidth(1, False))); //77px

  vstTable.BeginUpdate;
  
  Node := vstTable.FocusedNode;
  if Assigned(Node) then
  begin
    Data := vstTable.GetNodeData(Node);
    if Assigned(Data) then
    begin
      Data^.Name := Data^.Name + 'xyz 12345';
      Data^.Desc := Data^.Desc + 'xyz 12345';
    end;
  end;

  vstTable.EndUpdate;

  //Workaround or musst have?
  //vstTable.InvalidateNode(Node);

  ShowMessage(IntToStr(vstTable.GetMaxColumnWidth(0, False))); //62px and 106px with the "workaround"
  ShowMessage(IntToStr(vstTable.GetMaxColumnWidth(1, False))); //127px

  vstTable.Header.AutoFitColumns(False, smaAllColumns);
end;

procedure TForm2.FormCreate(Sender: TObject);
var
  Node: PVirtualNode;
  Data: PMyDataSet;
  Index: Integer;
  
begin

  vstTable.NodeDataSize := SizeOf(TMyDataSet);
  vstTable.BeginUpdate;

  for Index := 1 to 10 do
  begin
    Node := vstTable.AddChild(nil);
    Data := vstTable.GetNodeData(Node);
    if Assigned(Data) then
    begin
      Data^.Name := IntToStr(Index)+'. Bla bla';
      Data^.Desc := 'Bla bla bla bla';
    end;
  end;

  vstTable.EndUpdate;

  vstTable.Header.AutoFitColumns(False, smaAllColumns);
  
end;

procedure TForm2.vstTableGetText(Sender: TBaseVirtualTree; Node: PVirtualNode;
  Column: TColumnIndex; TextType: TVSTTextType; var CellText: string);
var
  Data: PMyDataSet;
  
begin
  Data := vstTable.GetNodeData(Node);
  if Assigned(Data) then
  begin
    case Column of
      0: CellText := Data^.Name;
      1: CellText := Data^.Desc;
    end;
  end;
  
end;

end.
  Mit Zitat antworten Zitat
Themen-Optionen Thema durchsuchen
Thema durchsuchen:

Erweiterte Suche
Ansicht

Forumregeln

Es ist dir nicht erlaubt, neue Themen zu verfassen.
Es ist dir nicht erlaubt, auf Beiträge zu antworten.
Es ist dir nicht erlaubt, Anhänge hochzuladen.
Es ist dir nicht erlaubt, deine Beiträge zu bearbeiten.

BB-Code ist an.
Smileys sind an.
[IMG] Code ist an.
HTML-Code ist aus.
Trackbacks are an
Pingbacks are an
Refbacks are aus

Gehe zu:

Impressum · AGB · Datenschutz · Nach oben
Alle Zeitangaben in WEZ +1. Es ist jetzt 23:07 Uhr.
Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz